Issue #11930: Remove deprecated time.accept2dyear.
This commit is contained in:
parent
314b92b26e
commit
03163ac185
|
@ -41,25 +41,6 @@ An explanation of some terminology and conventions is in order.
|
||||||
parsed, they are converted according to the POSIX and ISO C standards: values
|
parsed, they are converted according to the POSIX and ISO C standards: values
|
||||||
69--99 are mapped to 1969--1999, and values 0--68 are mapped to 2000--2068.
|
69--99 are mapped to 1969--1999, and values 0--68 are mapped to 2000--2068.
|
||||||
|
|
||||||
For backward compatibility, years with less than 4 digits are treated
|
|
||||||
specially by :func:`asctime`, :func:`mktime`, and :func:`strftime` functions
|
|
||||||
that operate on a 9-tuple or :class:`struct_time` values. If year (the first
|
|
||||||
value in the 9-tuple) is specified with less than 4 digits, its interpretation
|
|
||||||
depends on the value of ``accept2dyear`` variable.
|
|
||||||
|
|
||||||
If ``accept2dyear`` is true (default), a backward compatibility behavior is
|
|
||||||
invoked as follows:
|
|
||||||
|
|
||||||
- for 2-digit year, century is guessed according to POSIX rules for
|
|
||||||
``%y`` strptime format. A deprecation warning is issued when century
|
|
||||||
information is guessed in this way.
|
|
||||||
|
|
||||||
- for 3-digit or negative year, a :exc:`ValueError` exception is raised.
|
|
||||||
|
|
||||||
If ``accept2dyear`` is false (set by the program or as a result of a
|
|
||||||
non-empty value assigned to ``PYTHONY2K`` environment variable) all year
|
|
||||||
values are interpreted as given.
|
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: UTC
|
single: UTC
|
||||||
single: Coordinated Universal Time
|
single: Coordinated Universal Time
|
||||||
|
@ -117,24 +98,6 @@ An explanation of some terminology and conventions is in order.
|
||||||
|
|
||||||
The module defines the following functions and data items:
|
The module defines the following functions and data items:
|
||||||
|
|
||||||
|
|
||||||
.. data:: accept2dyear
|
|
||||||
|
|
||||||
Boolean value indicating whether two-digit year values will be
|
|
||||||
mapped to 1969--2068 range by :func:`asctime`, :func:`mktime`, and
|
|
||||||
:func:`strftime` functions. This is true by default, but will be
|
|
||||||
set to false if the environment variable :envvar:`PYTHONY2K` has
|
|
||||||
been set to a non-empty string. It may also be modified at run
|
|
||||||
time.
|
|
||||||
|
|
||||||
.. deprecated:: 3.2
|
|
||||||
Mapping of 2-digit year values by :func:`asctime`,
|
|
||||||
:func:`mktime`, and :func:`strftime` functions to 1969--2068
|
|
||||||
range is deprecated. Programs that need to process 2-digit
|
|
||||||
years should use ``%y`` code available in :func:`strptime`
|
|
||||||
function or convert 2-digit year values to 4-digit themselves.
|
|
||||||
|
|
||||||
|
|
||||||
.. data:: altzone
|
.. data:: altzone
|
||||||
|
|
||||||
The offset of the local DST timezone, in seconds west of UTC, if one is defined.
|
The offset of the local DST timezone, in seconds west of UTC, if one is defined.
|
||||||
|
@ -308,7 +271,7 @@ The module defines the following functions and data items:
|
||||||
| ``%y`` | Year without century as a decimal number | |
|
| ``%y`` | Year without century as a decimal number | |
|
||||||
| | [00,99]. | |
|
| | [00,99]. | |
|
||||||
+-----------+------------------------------------------------+-------+
|
+-----------+------------------------------------------------+-------+
|
||||||
| ``%Y`` | Year with century as a decimal number. | \(4) |
|
| ``%Y`` | Year with century as a decimal number. | |
|
||||||
| | | |
|
| | | |
|
||||||
+-----------+------------------------------------------------+-------+
|
+-----------+------------------------------------------------+-------+
|
||||||
| ``%Z`` | Time zone name (no characters if no time zone | |
|
| ``%Z`` | Time zone name (no characters if no time zone | |
|
||||||
|
@ -332,12 +295,6 @@ The module defines the following functions and data items:
|
||||||
When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in
|
When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in
|
||||||
calculations when the day of the week and the year are specified.
|
calculations when the day of the week and the year are specified.
|
||||||
|
|
||||||
(4)
|
|
||||||
Produces different results depending on the value of
|
|
||||||
``time.accept2dyear`` variable. See :ref:`Year 2000 (Y2K)
|
|
||||||
issues <time-y2kissues>` for details.
|
|
||||||
|
|
||||||
|
|
||||||
Here is an example, a format for dates compatible with that specified in the
|
Here is an example, a format for dates compatible with that specified in the
|
||||||
:rfc:`2822` Internet email standard. [#]_ ::
|
:rfc:`2822` Internet email standard. [#]_ ::
|
||||||
|
|
||||||
|
@ -418,8 +375,7 @@ The module defines the following functions and data items:
|
||||||
+-------+-------------------+---------------------------------+
|
+-------+-------------------+---------------------------------+
|
||||||
|
|
||||||
Note that unlike the C structure, the month value is a range of [1, 12], not
|
Note that unlike the C structure, the month value is a range of [1, 12], not
|
||||||
[0, 11]. A year value will be handled as described under :ref:`Year 2000
|
[0, 11]. A ``-1`` argument as the daylight
|
||||||
(Y2K) issues <time-y2kissues>` above. A ``-1`` argument as the daylight
|
|
||||||
savings flag, passed to :func:`mktime` will usually result in the correct
|
savings flag, passed to :func:`mktime` will usually result in the correct
|
||||||
daylight savings state to be filled in.
|
daylight savings state to be filled in.
|
||||||
|
|
||||||
|
|
|
@ -96,12 +96,13 @@ class TimeTestCase(unittest.TestCase):
|
||||||
self._bounds_checking(lambda tup: time.strftime('', tup))
|
self._bounds_checking(lambda tup: time.strftime('', tup))
|
||||||
|
|
||||||
def test_default_values_for_zero(self):
|
def test_default_values_for_zero(self):
|
||||||
# Make sure that using all zeros uses the proper default values.
|
# Make sure that using all zeros uses the proper default
|
||||||
# No test for daylight savings since strftime() does not change output
|
# values. No test for daylight savings since strftime() does
|
||||||
# based on its value.
|
# not change output based on its value and no test for year
|
||||||
|
# because systems vary in their support for year 0.
|
||||||
expected = "2000 01 01 00 00 00 1 001"
|
expected = "2000 01 01 00 00 00 1 001"
|
||||||
with support.check_warnings():
|
with support.check_warnings():
|
||||||
result = time.strftime("%Y %m %d %H %M %S %w %j", (0,)*9)
|
result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8)
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
def test_strptime(self):
|
def test_strptime(self):
|
||||||
|
@ -271,15 +272,6 @@ class TestLocale(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class _BaseYearTest(unittest.TestCase):
|
class _BaseYearTest(unittest.TestCase):
|
||||||
accept2dyear = None
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.saved_accept2dyear = time.accept2dyear
|
|
||||||
time.accept2dyear = self.accept2dyear
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
time.accept2dyear = self.saved_accept2dyear
|
|
||||||
|
|
||||||
def yearstr(self, y):
|
def yearstr(self, y):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -306,23 +298,7 @@ class _TestStrftimeYear:
|
||||||
self.assertEqual(text, '12345')
|
self.assertEqual(text, '12345')
|
||||||
self.assertEqual(self.yearstr(123456789), '123456789')
|
self.assertEqual(self.yearstr(123456789), '123456789')
|
||||||
|
|
||||||
class _Test2dYear(_BaseYearTest):
|
|
||||||
accept2dyear = 1
|
|
||||||
|
|
||||||
def test_year(self):
|
|
||||||
with support.check_warnings():
|
|
||||||
self.assertEqual(self.yearstr(0), '2000')
|
|
||||||
self.assertEqual(self.yearstr(69), '1969')
|
|
||||||
self.assertEqual(self.yearstr(68), '2068')
|
|
||||||
self.assertEqual(self.yearstr(99), '1999')
|
|
||||||
|
|
||||||
def test_invalid(self):
|
|
||||||
self.assertRaises(ValueError, self.yearstr, -1)
|
|
||||||
self.assertRaises(ValueError, self.yearstr, 100)
|
|
||||||
self.assertRaises(ValueError, self.yearstr, 999)
|
|
||||||
|
|
||||||
class _Test4dYear(_BaseYearTest):
|
class _Test4dYear(_BaseYearTest):
|
||||||
accept2dyear = 0
|
|
||||||
|
|
||||||
def test_year(self):
|
def test_year(self):
|
||||||
self.assertIn(self.yearstr(1), ('1', '0001'))
|
self.assertIn(self.yearstr(1), ('1', '0001'))
|
||||||
|
@ -361,46 +337,19 @@ class _Test4dYear(_BaseYearTest):
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class TestAsctimeAccept2dYear(_TestAsctimeYear, _Test2dYear):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class TestStrftimeAccept2dYear(_TestStrftimeYear, _Test2dYear):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class TestAsctime4dyear(_TestAsctimeYear, _Test4dYear):
|
class TestAsctime4dyear(_TestAsctimeYear, _Test4dYear):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class TestStrftime4dyear(_TestStrftimeYear, _Test4dYear):
|
class TestStrftime4dyear(_TestStrftimeYear, _Test4dYear):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Test2dyearBool(_TestAsctimeYear, _Test2dYear):
|
|
||||||
accept2dyear = True
|
|
||||||
|
|
||||||
class Test4dyearBool(_TestAsctimeYear, _Test4dYear):
|
|
||||||
accept2dyear = False
|
|
||||||
|
|
||||||
class TestAccept2YearBad(_TestAsctimeYear, _BaseYearTest):
|
|
||||||
class X:
|
|
||||||
def __bool__(self):
|
|
||||||
raise RuntimeError('boo')
|
|
||||||
accept2dyear = X()
|
|
||||||
def test_2dyear(self):
|
|
||||||
pass
|
|
||||||
def test_invalid(self):
|
|
||||||
self.assertRaises(RuntimeError, self.yearstr, 200)
|
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(
|
support.run_unittest(
|
||||||
TimeTestCase,
|
TimeTestCase,
|
||||||
TestLocale,
|
TestLocale,
|
||||||
TestAsctimeAccept2dYear,
|
|
||||||
TestStrftimeAccept2dYear,
|
|
||||||
TestAsctime4dyear,
|
TestAsctime4dyear,
|
||||||
TestStrftime4dyear,
|
TestStrftime4dyear)
|
||||||
Test2dyearBool,
|
|
||||||
Test4dyearBool,
|
|
||||||
TestAccept2YearBad)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_main()
|
test_main()
|
||||||
|
|
|
@ -66,9 +66,6 @@ static long main_thread;
|
||||||
static int floatsleep(double);
|
static int floatsleep(double);
|
||||||
static double floattime(void);
|
static double floattime(void);
|
||||||
|
|
||||||
/* For Y2K check */
|
|
||||||
static PyObject *moddict;
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
time_time(PyObject *self, PyObject *unused)
|
time_time(PyObject *self, PyObject *unused)
|
||||||
{
|
{
|
||||||
|
@ -311,49 +308,6 @@ gettmarg(PyObject *args, struct tm *p)
|
||||||
&p->tm_hour, &p->tm_min, &p->tm_sec,
|
&p->tm_hour, &p->tm_min, &p->tm_sec,
|
||||||
&p->tm_wday, &p->tm_yday, &p->tm_isdst))
|
&p->tm_wday, &p->tm_yday, &p->tm_isdst))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If year is specified with less than 4 digits, its interpretation
|
|
||||||
* depends on the accept2dyear value.
|
|
||||||
*
|
|
||||||
* If accept2dyear is true (default), a backward compatibility behavior is
|
|
||||||
* invoked as follows:
|
|
||||||
*
|
|
||||||
* - for 2-digit year, century is guessed according to POSIX rules for
|
|
||||||
* %y strptime format: 21st century for y < 69, 20th century
|
|
||||||
* otherwise. A deprecation warning is issued when century
|
|
||||||
* information is guessed in this way.
|
|
||||||
*
|
|
||||||
* - for 3-digit or negative year, a ValueError exception is raised.
|
|
||||||
*
|
|
||||||
* If accept2dyear is false (set by the program or as a result of a
|
|
||||||
* non-empty value assigned to PYTHONY2K environment variable) all year
|
|
||||||
* values are interpreted as given.
|
|
||||||
*/
|
|
||||||
if (y < 1000) {
|
|
||||||
PyObject *accept = PyDict_GetItemString(moddict,
|
|
||||||
"accept2dyear");
|
|
||||||
if (accept != NULL) {
|
|
||||||
int acceptval = PyObject_IsTrue(accept);
|
|
||||||
if (acceptval == -1)
|
|
||||||
return 0;
|
|
||||||
if (acceptval) {
|
|
||||||
if (0 <= y && y < 69)
|
|
||||||
y += 2000;
|
|
||||||
else if (69 <= y && y < 100)
|
|
||||||
y += 1900;
|
|
||||||
else {
|
|
||||||
PyErr_SetString(PyExc_ValueError,
|
|
||||||
"year out of range");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
|
||||||
"Century info guessed for a 2-digit year.", 1) != 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p->tm_year = y - 1900;
|
p->tm_year = y - 1900;
|
||||||
p->tm_mon--;
|
p->tm_mon--;
|
||||||
p->tm_wday = (p->tm_wday + 1) % 7;
|
p->tm_wday = (p->tm_wday + 1) % 7;
|
||||||
|
@ -863,7 +817,7 @@ The actual value can be retrieved by calling gmtime(0).\n\
|
||||||
\n\
|
\n\
|
||||||
The other representation is a tuple of 9 integers giving local time.\n\
|
The other representation is a tuple of 9 integers giving local time.\n\
|
||||||
The tuple items are:\n\
|
The tuple items are:\n\
|
||||||
year (four digits, e.g. 1998)\n\
|
year (including century, e.g. 1998)\n\
|
||||||
month (1-12)\n\
|
month (1-12)\n\
|
||||||
day (1-31)\n\
|
day (1-31)\n\
|
||||||
hours (0-23)\n\
|
hours (0-23)\n\
|
||||||
|
@ -920,13 +874,6 @@ PyInit_time(void)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
|
|
||||||
p = Py_GETENV("PYTHONY2K");
|
|
||||||
PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p));
|
|
||||||
/* Squirrel away the module's dictionary for the y2k check */
|
|
||||||
moddict = PyModule_GetDict(m);
|
|
||||||
Py_INCREF(moddict);
|
|
||||||
|
|
||||||
/* Set, or reset, module variables like time.timezone */
|
/* Set, or reset, module variables like time.timezone */
|
||||||
PyInit_timezone(m);
|
PyInit_timezone(m);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue