mirror of https://github.com/python/cpython
Strengthen the tests for format '%Y', in relation with issue #13305.
This commit is contained in:
parent
b6dbc9ee15
commit
49ce06858b
|
@ -1291,8 +1291,16 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
|
||||||
|
|
||||||
def test_strftime_y2k(self):
|
def test_strftime_y2k(self):
|
||||||
for y in (1, 49, 70, 99, 100, 999, 1000, 1970):
|
for y in (1, 49, 70, 99, 100, 999, 1000, 1970):
|
||||||
self.assertIn(self.theclass(y, 1, 1).strftime("%Y"),
|
d = self.theclass(y, 1, 1)
|
||||||
[str(y),'%04d' % y])
|
# Issue 13305: For years < 1000, the value is not always
|
||||||
|
# padded to 4 digits across platforms. The C standard
|
||||||
|
# assumes year >= 1900, so it does not specify the number
|
||||||
|
# of digits.
|
||||||
|
if d.strftime("%Y") != '%04d' % y:
|
||||||
|
# Year 42 returns '42', not padded
|
||||||
|
self.assertEqual(d.strftime("%Y"), '%d' % y)
|
||||||
|
# '0042' is obtained anyway
|
||||||
|
self.assertEqual(d.strftime("%4Y"), '%04d' % y)
|
||||||
|
|
||||||
def test_replace(self):
|
def test_replace(self):
|
||||||
cls = self.theclass
|
cls = self.theclass
|
||||||
|
|
|
@ -70,28 +70,35 @@ class TimeTestCase(unittest.TestCase):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
time.strftime('%f')
|
time.strftime('%f')
|
||||||
|
|
||||||
def _bounds_checking(self, func=time.strftime):
|
def _bounds_checking(self, func):
|
||||||
# Make sure that strftime() checks the bounds of the various parts
|
# Make sure that strftime() checks the bounds of the various parts
|
||||||
#of the time tuple (0 is valid for *all* values).
|
# of the time tuple (0 is valid for *all* values).
|
||||||
|
|
||||||
# The year field is tested by other test cases above
|
# The year field is tested by other test cases above
|
||||||
|
|
||||||
# Check month [1, 12] + zero support
|
# Check month [1, 12] + zero support
|
||||||
|
func((1900, 0, 1, 0, 0, 0, 0, 1, -1))
|
||||||
|
func((1900, 12, 1, 0, 0, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, -1, 1, 0, 0, 0, 0, 1, -1))
|
(1900, -1, 1, 0, 0, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 13, 1, 0, 0, 0, 0, 1, -1))
|
(1900, 13, 1, 0, 0, 0, 0, 1, -1))
|
||||||
# Check day of month [1, 31] + zero support
|
# Check day of month [1, 31] + zero support
|
||||||
|
func((1900, 1, 0, 0, 0, 0, 0, 1, -1))
|
||||||
|
func((1900, 1, 31, 0, 0, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, -1, 0, 0, 0, 0, 1, -1))
|
(1900, 1, -1, 0, 0, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 32, 0, 0, 0, 0, 1, -1))
|
(1900, 1, 32, 0, 0, 0, 0, 1, -1))
|
||||||
# Check hour [0, 23]
|
# Check hour [0, 23]
|
||||||
|
func((1900, 1, 1, 0, 0, 0, 0, 1, -1))
|
||||||
|
func((1900, 1, 1, 23, 0, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 1, -1, 0, 0, 0, 1, -1))
|
(1900, 1, 1, -1, 0, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 1, 24, 0, 0, 0, 1, -1))
|
(1900, 1, 1, 24, 0, 0, 0, 1, -1))
|
||||||
# Check minute [0, 59]
|
# Check minute [0, 59]
|
||||||
|
func((1900, 1, 1, 0, 59, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 1, 0, -1, 0, 0, 1, -1))
|
(1900, 1, 1, 0, -1, 0, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
|
@ -101,15 +108,21 @@ class TimeTestCase(unittest.TestCase):
|
||||||
(1900, 1, 1, 0, 0, -1, 0, 1, -1))
|
(1900, 1, 1, 0, 0, -1, 0, 1, -1))
|
||||||
# C99 only requires allowing for one leap second, but Python's docs say
|
# C99 only requires allowing for one leap second, but Python's docs say
|
||||||
# allow two leap seconds (0..61)
|
# allow two leap seconds (0..61)
|
||||||
|
func((1900, 1, 1, 0, 0, 60, 0, 1, -1))
|
||||||
|
func((1900, 1, 1, 0, 0, 61, 0, 1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 1, 0, 0, 62, 0, 1, -1))
|
(1900, 1, 1, 0, 0, 62, 0, 1, -1))
|
||||||
# No check for upper-bound day of week;
|
# No check for upper-bound day of week;
|
||||||
# value forced into range by a ``% 7`` calculation.
|
# value forced into range by a ``% 7`` calculation.
|
||||||
# Start check at -2 since gettmarg() increments value before taking
|
# Start check at -2 since gettmarg() increments value before taking
|
||||||
# modulo.
|
# modulo.
|
||||||
|
self.assertEqual(func((1900, 1, 1, 0, 0, 0, -1, 1, -1)),
|
||||||
|
func((1900, 1, 1, 0, 0, 0, +6, 1, -1)))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 1, 0, 0, 0, -2, 1, -1))
|
(1900, 1, 1, 0, 0, 0, -2, 1, -1))
|
||||||
# Check day of the year [1, 366] + zero support
|
# Check day of the year [1, 366] + zero support
|
||||||
|
func((1900, 1, 1, 0, 0, 0, 0, 0, -1))
|
||||||
|
func((1900, 1, 1, 0, 0, 0, 0, 366, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
(1900, 1, 1, 0, 0, 0, 0, -1, -1))
|
(1900, 1, 1, 0, 0, 0, 0, -1, -1))
|
||||||
self.assertRaises(ValueError, func,
|
self.assertRaises(ValueError, func,
|
||||||
|
@ -299,6 +312,8 @@ class _BaseYearTest(unittest.TestCase):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
class _TestAsctimeYear:
|
class _TestAsctimeYear:
|
||||||
|
_format = '%d'
|
||||||
|
|
||||||
def yearstr(self, y):
|
def yearstr(self, y):
|
||||||
return time.asctime((y,) + (0,) * 8).split()[-1]
|
return time.asctime((y,) + (0,) * 8).split()[-1]
|
||||||
|
|
||||||
|
@ -308,8 +323,41 @@ class _TestAsctimeYear:
|
||||||
self.assertEqual(self.yearstr(123456789), '123456789')
|
self.assertEqual(self.yearstr(123456789), '123456789')
|
||||||
|
|
||||||
class _TestStrftimeYear:
|
class _TestStrftimeYear:
|
||||||
|
|
||||||
|
# Issue 13305: For years < 1000, the value is not always
|
||||||
|
# padded to 4 digits across platforms. The C standard
|
||||||
|
# assumes year >= 1900, so it does not specify the number
|
||||||
|
# of digits.
|
||||||
|
|
||||||
|
if time.strftime('%Y', (1,) + (0,) * 8) == '0001':
|
||||||
|
_format = '%04d'
|
||||||
|
else:
|
||||||
|
_format = '%d'
|
||||||
|
|
||||||
def yearstr(self, y):
|
def yearstr(self, y):
|
||||||
return time.strftime('%Y', (y,) + (0,) * 8).split()[-1]
|
return time.strftime('%Y', (y,) + (0,) * 8)
|
||||||
|
|
||||||
|
def test_4dyear(self):
|
||||||
|
# Check that we can return the zero padded value.
|
||||||
|
if self._format == '%04d':
|
||||||
|
self.test_year('%04d')
|
||||||
|
else:
|
||||||
|
def year4d(y):
|
||||||
|
return time.strftime('%4Y', (y,) + (0,) * 8)
|
||||||
|
self.test_year('%04d', func=year4d)
|
||||||
|
|
||||||
|
class _Test4dYear(_BaseYearTest):
|
||||||
|
_format = '%d'
|
||||||
|
|
||||||
|
def test_year(self, fmt=None, func=None):
|
||||||
|
fmt = fmt or self._format
|
||||||
|
func = func or self.yearstr
|
||||||
|
self.assertEqual(func(1), fmt % 1)
|
||||||
|
self.assertEqual(func(68), fmt % 68)
|
||||||
|
self.assertEqual(func(69), fmt % 69)
|
||||||
|
self.assertEqual(func(99), fmt % 99)
|
||||||
|
self.assertEqual(func(999), fmt % 999)
|
||||||
|
self.assertEqual(func(9999), fmt % 9999)
|
||||||
|
|
||||||
def test_large_year(self):
|
def test_large_year(self):
|
||||||
# Check that it doesn't crash for year > 9999
|
# Check that it doesn't crash for year > 9999
|
||||||
|
@ -321,23 +369,13 @@ class _TestStrftimeYear:
|
||||||
self.assertEqual(text, '12345')
|
self.assertEqual(text, '12345')
|
||||||
self.assertEqual(self.yearstr(123456789), '123456789')
|
self.assertEqual(self.yearstr(123456789), '123456789')
|
||||||
|
|
||||||
class _Test4dYear(_BaseYearTest):
|
|
||||||
|
|
||||||
def test_year(self):
|
|
||||||
self.assertIn(self.yearstr(1), ('1', '0001'))
|
|
||||||
self.assertIn(self.yearstr(68), ('68', '0068'))
|
|
||||||
self.assertIn(self.yearstr(69), ('69', '0069'))
|
|
||||||
self.assertIn(self.yearstr(99), ('99', '0099'))
|
|
||||||
self.assertIn(self.yearstr(999), ('999', '0999'))
|
|
||||||
self.assertEqual(self.yearstr(9999), '9999')
|
|
||||||
|
|
||||||
def test_negative(self):
|
def test_negative(self):
|
||||||
try:
|
try:
|
||||||
text = self.yearstr(-1)
|
text = self.yearstr(-1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# strftime() is limited to [1; 9999] with Visual Studio
|
# strftime() is limited to [1; 9999] with Visual Studio
|
||||||
return
|
return
|
||||||
self.assertIn(text, ('-1', '-001'))
|
self.assertEqual(text, self._format % -1)
|
||||||
|
|
||||||
self.assertEqual(self.yearstr(-1234), '-1234')
|
self.assertEqual(self.yearstr(-1234), '-1234')
|
||||||
self.assertEqual(self.yearstr(-123456), '-123456')
|
self.assertEqual(self.yearstr(-123456), '-123456')
|
||||||
|
|
Loading…
Reference in New Issue