diff options
Diffstat (limited to 'Lib/test/datetimetester.py')
| -rw-r--r-- | Lib/test/datetimetester.py | 136 |
1 files changed, 126 insertions, 10 deletions
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index ab55476..289b0ca 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3,8 +3,10 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ +import copy import sys import pickle +import random import unittest from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod @@ -49,6 +51,33 @@ class TestModule(unittest.TestCase): self.assertEqual(datetime.MINYEAR, 1) self.assertEqual(datetime.MAXYEAR, 9999) + def test_divide_and_round(self): + if '_Fast' in str(self): + return + dar = datetime_module._divide_and_round + + self.assertEqual(dar(-10, -3), 3) + self.assertEqual(dar(5, -2), -2) + + # four cases: (2 signs of a) x (2 signs of b) + self.assertEqual(dar(7, 3), 2) + self.assertEqual(dar(-7, 3), -2) + self.assertEqual(dar(7, -3), -2) + self.assertEqual(dar(-7, -3), 2) + + # ties to even - eight cases: + # (2 signs of a) x (2 signs of b) x (even / odd quotient) + self.assertEqual(dar(10, 4), 2) + self.assertEqual(dar(-10, 4), -2) + self.assertEqual(dar(10, -4), -2) + self.assertEqual(dar(-10, -4), 2) + + self.assertEqual(dar(6, 4), 2) + self.assertEqual(dar(-6, 4), -2) + self.assertEqual(dar(6, -4), -2) + self.assertEqual(dar(-6, -4), 2) + + ############################################################################# # tzinfo tests @@ -76,8 +105,18 @@ class PicklableFixedOffset(FixedOffset): def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) +class _TZInfo(tzinfo): + def utcoffset(self, datetime_module): + return random.random() + class TestTZInfo(unittest.TestCase): + def test_refcnt_crash_bug_22044(self): + tz1 = _TZInfo() + dt1 = datetime(2014, 7, 21, 11, 32, 3, 0, tz1) + with self.assertRaises(TypeError): + dt1.utcoffset() + def test_non_abstractness(self): # In order to allow subclasses to get pickled, the C implementation # wasn't able to get away with having __init__ raise @@ -142,6 +181,29 @@ class TestTZInfo(unittest.TestCase): self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), oname) + def test_issue23600(self): + DSTDIFF = DSTOFFSET = timedelta(hours=1) + + class UKSummerTime(tzinfo): + """Simple time zone which pretends to always be in summer time, since + that's what shows the failure. + """ + + def utcoffset(self, dt): + return DSTOFFSET + + def dst(self, dt): + return DSTDIFF + + def tzname(self, dt): + return 'UKSummerTime' + + tz = UKSummerTime() + u = datetime(2014, 4, 26, 12, 1, tzinfo=tz) + t = tz.fromutc(u) + self.assertEqual(t - t.utcoffset(), u) + + class TestTimeZone(unittest.TestCase): def setUp(self): @@ -162,7 +224,6 @@ class TestTimeZone(unittest.TestCase): tzrep = repr(tz) self.assertEqual(tz, eval(tzrep)) - def test_class_members(self): limit = timedelta(hours=23, minutes=59) self.assertEqual(timezone.utc.utcoffset(None), ZERO) @@ -249,6 +310,33 @@ class TestTimeZone(unittest.TestCase): self.assertEqual(tz.dst(t), t.replace(tzinfo=tz).dst()) + def test_pickle(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertIs(tz_copy, tz) + + def test_copy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.copy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.copy(tz) + self.assertIs(tz_copy, tz) + + def test_deepcopy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.deepcopy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.deepcopy(tz) + self.assertIs(tz_copy, tz) + + ############################################################################# # Base class for testing a particular aspect of timedelta, time, date and # datetime comparisons. @@ -371,6 +459,10 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): eq((-3*us) * 0.5, -2*us) eq((-5*us) * 0.5, -2*us) + # Issue #23521 + eq(td(seconds=1) * 0.123456, td(microseconds=123456)) + eq(td(seconds=1) * 0.6112295, td(microseconds=611229)) + # Division by int and float eq((3*us) / 2, 2*us) eq((5*us) / 2, 2*us) @@ -385,6 +477,9 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): for i in range(-10, 10): eq((i*us/-3)//us, round(i/-3)) + # Issue #23521 + eq(td(seconds=1) / (1 / 0.6112295), td(microseconds=611229)) + # Issue #11576 eq(td(999999999, 86399, 999999) - td(999999999, 86399, 999998), td(0, 0, 1)) @@ -605,8 +700,16 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): # Single-field rounding. eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0 eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0 + eq(td(milliseconds=0.5/1000), td(microseconds=0)) + eq(td(milliseconds=-0.5/1000), td(microseconds=-0)) eq(td(milliseconds=0.6/1000), td(microseconds=1)) eq(td(milliseconds=-0.6/1000), td(microseconds=-1)) + eq(td(milliseconds=1.5/1000), td(microseconds=2)) + eq(td(milliseconds=-1.5/1000), td(microseconds=-2)) + eq(td(seconds=0.5/10**6), td(microseconds=0)) + eq(td(seconds=-0.5/10**6), td(microseconds=-0)) + eq(td(seconds=1/2**7), td(microseconds=7812)) + eq(td(seconds=-1/2**7), td(microseconds=-7812)) # Rounding due to contributions from more than one field. us_per_hour = 3600e6 @@ -619,6 +722,10 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): eq(td(hours=-.2/us_per_hour), td(0)) eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1)) + # Test for a patch in Issue 8860 + eq(td(microseconds=0.5), 0.5*td(microseconds=1.0)) + eq(td(microseconds=0.5)//td.resolution, 0.5*td.resolution//td.resolution) + def test_massive_normalization(self): td = timedelta(microseconds=-1) self.assertEqual((td.days, td.seconds, td.microseconds), @@ -1667,11 +1774,12 @@ class TestDateTime(TestDate): def test_more_pickling(self): a = self.theclass(2003, 2, 7, 16, 48, 37, 444116) - s = pickle.dumps(a) - b = pickle.loads(s) - self.assertEqual(b.year, 2003) - self.assertEqual(b.month, 2) - self.assertEqual(b.day, 7) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(a, proto) + b = pickle.loads(s) + self.assertEqual(b.year, 2003) + self.assertEqual(b.month, 2) + self.assertEqual(b.day, 7) def test_pickling_subclass_datetime(self): args = 6, 7, 23, 20, 59, 1, 64**2 @@ -1774,12 +1882,14 @@ class TestDateTime(TestDate): tzinfo=timezone(timedelta(hours=-5), 'EST')) self.assertEqual(t.timestamp(), 18000 + 3600 + 2*60 + 3 + 4*1e-6) + def test_microsecond_rounding(self): for fts in [self.theclass.fromtimestamp, self.theclass.utcfromtimestamp]: zero = fts(0) self.assertEqual(zero.second, 0) self.assertEqual(zero.microsecond, 0) + one = fts(1e-6) try: minus_one = fts(-1e-6) except OSError: @@ -1790,22 +1900,28 @@ class TestDateTime(TestDate): self.assertEqual(minus_one.microsecond, 999999) t = fts(-1e-8) - self.assertEqual(t, minus_one) + self.assertEqual(t, zero) t = fts(-9e-7) self.assertEqual(t, minus_one) t = fts(-1e-7) - self.assertEqual(t, minus_one) + self.assertEqual(t, zero) + t = fts(-1/2**7) + self.assertEqual(t.second, 59) + self.assertEqual(t.microsecond, 992188) t = fts(1e-7) self.assertEqual(t, zero) t = fts(9e-7) - self.assertEqual(t, zero) + self.assertEqual(t, one) t = fts(0.99999949) self.assertEqual(t.second, 0) self.assertEqual(t.microsecond, 999999) t = fts(0.9999999) + self.assertEqual(t.second, 1) + self.assertEqual(t.microsecond, 0) + t = fts(1/2**7) self.assertEqual(t.second, 0) - self.assertEqual(t.microsecond, 999999) + self.assertEqual(t.microsecond, 7812) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, |
