Issue #11930: Remove deprecated time.accept2dyear.

This commit is contained in:
Alexander Belopolsky 2011-05-02 12:20:52 -04:00
parent 314b92b26e
commit 03163ac185
3 changed files with 9 additions and 157 deletions

View File

@ -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.

View File

@ -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()

View File

@ -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);