diff options
author | Tim Peters <tim.peters@gmail.com> | 2002-12-22 03:43:39 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2002-12-22 03:43:39 (GMT) |
commit | 855fe88b241a512d21b7c716fcae88331ae50a98 (patch) | |
tree | 1f8a5d88c5c76d4701bd80d28178e5e7384a2868 /Lib | |
parent | 18091540db294eb4566129a9b8bacb85a676a205 (diff) | |
download | cpython-855fe88b241a512d21b7c716fcae88331ae50a98.zip cpython-855fe88b241a512d21b7c716fcae88331ae50a98.tar.gz cpython-855fe88b241a512d21b7c716fcae88331ae50a98.tar.bz2 |
Implemented a Wiki suggestion:
{timetz,datetimetz}.{utcoffset,dst}() now return a timedelta (or None)
instead of an int (or None).
tzinfo.{utcoffset,dst)() can now return a timedelta (or an int, or None).
Curiously, this was much easier to do in the C implementation than in the
Python implementation (which lives in the Zope3 code tree) -- the C code
already had lots of hair to extract C ints from offset objects, and used
C ints internally.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_datetime.py | 189 |
1 files changed, 118 insertions, 71 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 9fd38f1..ca26872 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -1458,35 +1458,120 @@ class TestTime(unittest.TestCase): self.failUnless(not cls(0)) self.failUnless(not cls()) - -class TestTimeTZ(TestTime): - - theclass = timetz - - def test_empty(self): - t = self.theclass() - self.assertEqual(t.hour, 0) - self.assertEqual(t.minute, 0) - self.assertEqual(t.second, 0) - self.assertEqual(t.microsecond, 0) - self.failUnless(t.tzinfo is None) +# A mixin for classes with a tzinfo= argument. Subclasses must define +# theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) +# must be legit (which is true for timetz and datetimetz). +class TZInfoBase(unittest.TestCase): def test_bad_tzinfo_classes(self): - tz = self.theclass - self.assertRaises(TypeError, tz, tzinfo=12) + cls = self.theclass + self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=12) class NiceTry(object): def __init__(self): pass def utcoffset(self, dt): pass - self.assertRaises(TypeError, tz, tzinfo=NiceTry) + self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=NiceTry) class BetterTry(tzinfo): def __init__(self): pass def utcoffset(self, dt): pass b = BetterTry() - t = tz(tzinfo=b) + t = cls(1, 1, 1, tzinfo=b) self.failUnless(t.tzinfo is b) + def test_utc_offset_out_of_bounds(self): + class Edgy(tzinfo): + def __init__(self, offset): + self.offset = offset + def utcoffset(self, dt): + return self.offset + + cls = self.theclass + for offset, legit in ((-1440, False), + (-1439, True), + (1439, True), + (1440, False)): + if cls is timetz: + t = cls(1, 2, 3, tzinfo=Edgy(offset)) + elif cls is datetimetz: + t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset)) + if legit: + aofs = abs(offset) + h, m = divmod(aofs, 60) + tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) + if isinstance(t, datetimetz): + t = t.timetz() + self.assertEqual(str(t), "01:02:03" + tag) + else: + self.assertRaises(ValueError, str, t) + + def test_tzinfo_classes(self): + cls = self.theclass + class C1(tzinfo): + def utcoffset(self, dt): return None + def dst(self, dt): return None + def tzname(self, dt): return None + for t in (cls(1, 1, 1), + cls(1, 1, 1, tzinfo=None), + cls(1, 1, 1, tzinfo=C1())): + self.failUnless(t.utcoffset() is None) + self.failUnless(t.dst() is None) + self.failUnless(t.tzname() is None) + + class C2(tzinfo): + def utcoffset(self, dt): return -1439 + def dst(self, dt): return 1439 + def tzname(self, dt): return "aname" + class C3(tzinfo): + def utcoffset(self, dt): return timedelta(minutes=-1439) + def dst(self, dt): return timedelta(minutes=1439) + def tzname(self, dt): return "aname" + for t in cls(1, 1, 1, tzinfo=C2()), cls(1, 1, 1, tzinfo=C3()): + self.assertEqual(t.utcoffset(), timedelta(minutes=-1439)) + self.assertEqual(t.dst(), timedelta(minutes=1439)) + self.assertEqual(t.tzname(), "aname") + + # Wrong types. + class C4(tzinfo): + def utcoffset(self, dt): return "aname" + def dst(self, dt): return () + def tzname(self, dt): return 0 + t = cls(1, 1, 1, tzinfo=C4()) + self.assertRaises(TypeError, t.utcoffset) + self.assertRaises(TypeError, t.dst) + self.assertRaises(TypeError, t.tzname) + + # Offset out of range. + class C5(tzinfo): + def utcoffset(self, dt): return -1440 + def dst(self, dt): return 1440 + class C6(tzinfo): + def utcoffset(self, dt): return timedelta(hours=-24) + def dst(self, dt): return timedelta(hours=24) + for t in cls(1, 1, 1, tzinfo=C5()), cls(1, 1, 1, tzinfo=C6()): + self.assertRaises(ValueError, t.utcoffset) + self.assertRaises(ValueError, t.dst) + + # Not a whole number of minutes. + class C7(tzinfo): + def utcoffset(self, dt): return timedelta(seconds=61) + def dst(self, dt): return timedelta(microseconds=-81) + t = cls(1, 1, 1, tzinfo=C7()) + self.assertRaises(ValueError, t.utcoffset) + self.assertRaises(ValueError, t.dst) + + +class TestTimeTZ(TestTime, TZInfoBase): + theclass = timetz + + def test_empty(self): + t = self.theclass() + self.assertEqual(t.hour, 0) + self.assertEqual(t.minute, 0) + self.assertEqual(t.second, 0) + self.assertEqual(t.microsecond, 0) + self.failUnless(t.tzinfo is None) + def test_zones(self): est = FixedOffset(-300, "EST", 1) utc = FixedOffset(0, "UTC", -2) @@ -1503,9 +1588,9 @@ class TestTimeTZ(TestTime): self.failUnless(t4.tzinfo is None) self.assertEqual(t5.tzinfo, utc) - self.assertEqual(t1.utcoffset(), -300) - self.assertEqual(t2.utcoffset(), 0) - self.assertEqual(t3.utcoffset(), 60) + self.assertEqual(t1.utcoffset(), timedelta(minutes=-300)) + self.assertEqual(t2.utcoffset(), timedelta(minutes=0)) + self.assertEqual(t3.utcoffset(), timedelta(minutes=60)) self.failUnless(t4.utcoffset() is None) self.assertRaises(TypeError, t1.utcoffset, "no args") @@ -1515,9 +1600,9 @@ class TestTimeTZ(TestTime): self.failUnless(t4.tzname() is None) self.assertRaises(TypeError, t1.tzname, "no args") - self.assertEqual(t1.dst(), 1) - self.assertEqual(t2.dst(), -2) - self.assertEqual(t3.dst(), 3) + self.assertEqual(t1.dst(), timedelta(minutes=1)) + self.assertEqual(t2.dst(), timedelta(minutes=-2)) + self.assertEqual(t3.dst(), timedelta(minutes=3)) self.failUnless(t4.dst() is None) self.assertRaises(TypeError, t1.dst, "no args") @@ -1578,26 +1663,6 @@ class TestTimeTZ(TestTime): t2 = self.theclass(23, 48, 6, 100, tzinfo=FixedOffset(-1010, "")) self.assertEqual(hash(t1), hash(t2)) - def test_utc_offset_out_of_bounds(self): - class Edgy(tzinfo): - def __init__(self, offset): - self.offset = offset - def utcoffset(self, dt): - return self.offset - - for offset, legit in ((-1440, False), - (-1439, True), - (1439, True), - (1440, False)): - t = timetz(1, 2, 3, tzinfo=Edgy(offset)) - if legit: - aofs = abs(offset) - h, m = divmod(aofs, 60) - tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) - self.assertEqual(str(t), "01:02:03" + tag) - else: - self.assertRaises(ValueError, str, t) - def test_pickling(self): import pickle, cPickle @@ -1623,7 +1688,7 @@ class TestTimeTZ(TestTime): derived.__setstate__(state) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), -300) + self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) self.assertEqual(derived.tzname(), 'cookie') for pickler in pickle, cPickle: @@ -1633,7 +1698,7 @@ class TestTimeTZ(TestTime): self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), -300) + self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): @@ -1664,8 +1729,7 @@ class TestTimeTZ(TestTime): t = cls(0, tzinfo=FixedOffset(-24*60, "")) self.assertRaises(ValueError, lambda: bool(t)) -class TestDateTimeTZ(TestDateTime): - +class TestDateTimeTZ(TestDateTime, TZInfoBase): theclass = datetimetz def test_trivial(self): @@ -1744,22 +1808,6 @@ class TestDateTimeTZ(TestDateTime): t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, "")) self.assertRaises(ValueError, lambda: t1 == t1) - def test_bad_tzinfo_classes(self): - tz = self.theclass - self.assertRaises(TypeError, tz, 1, 2, 3, tzinfo=12) - - class NiceTry(object): - def __init__(self): pass - def utcoffset(self, dt): pass - self.assertRaises(TypeError, tz, 1, 2, 3, tzinfo=NiceTry) - - class BetterTry(tzinfo): - def __init__(self): pass - def utcoffset(self, dt): pass - b = BetterTry() - t = tz(1, 2, 3, tzinfo=b) - self.failUnless(t.tzinfo is b) - def test_pickling(self): import pickle, cPickle @@ -1785,7 +1833,7 @@ class TestDateTimeTZ(TestDateTime): derived.__setstate__(state) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), -300) + self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) self.assertEqual(derived.tzname(), 'cookie') for pickler in pickle, cPickle: @@ -1795,7 +1843,7 @@ class TestDateTimeTZ(TestDateTime): self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), -300) + self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) self.assertEqual(derived.tzname(), 'cookie') def test_extreme_hashes(self): @@ -1822,9 +1870,9 @@ class TestDateTimeTZ(TestDateTime): self.assertEqual(t1.tzinfo, est) self.assertEqual(t2.tzinfo, utc) self.assertEqual(t3.tzinfo, met) - self.assertEqual(t1.utcoffset(), -300) - self.assertEqual(t2.utcoffset(), 0) - self.assertEqual(t3.utcoffset(), 60) + self.assertEqual(t1.utcoffset(), timedelta(minutes=-300)) + self.assertEqual(t2.utcoffset(), timedelta(minutes=0)) + self.assertEqual(t3.utcoffset(), timedelta(minutes=60)) self.assertEqual(t1.tzname(), "EST") self.assertEqual(t2.tzname(), "UTC") self.assertEqual(t3.tzname(), "MET") @@ -1914,8 +1962,7 @@ class TestDateTimeTZ(TestDateTime): # (nowaware base - nowawareplus base) + # (nowawareplus offset - nowaware offset) = # -delta + nowawareplus offset - nowaware offset - expected = timedelta(minutes=nowawareplus.utcoffset() - - nowaware.utcoffset()) - delta + expected = nowawareplus.utcoffset() - nowaware.utcoffset() - delta self.assertEqual(got, expected) # Try max possible difference. @@ -1935,7 +1982,7 @@ class TestDateTimeTZ(TestDateTime): another = meth(off42) again = meth(tzinfo=off42) self.failUnless(another.tzinfo is again.tzinfo) - self.assertEqual(another.utcoffset(), 42) + self.assertEqual(another.utcoffset(), timedelta(minutes=42)) # Bad argument with and w/o naming the keyword. self.assertRaises(TypeError, meth, 16) self.assertRaises(TypeError, meth, tzinfo=16) @@ -1955,7 +2002,7 @@ class TestDateTimeTZ(TestDateTime): another = meth(ts, off42) again = meth(ts, tzinfo=off42) self.failUnless(another.tzinfo is again.tzinfo) - self.assertEqual(another.utcoffset(), 42) + self.assertEqual(another.utcoffset(), timedelta(minutes=42)) # Bad argument with and w/o naming the keyword. self.assertRaises(TypeError, meth, ts, 16) self.assertRaises(TypeError, meth, ts, tzinfo=16) |