summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_datetime.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_datetime.py')
-rw-r--r--Lib/test/test_datetime.py200
1 files changed, 134 insertions, 66 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index 40eb3ab..735582f 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -3,7 +3,6 @@
See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
"""
-import os
import sys
import pickle
import cPickle
@@ -128,7 +127,7 @@ class TestTZInfo(unittest.TestCase):
# Base clase for testing a particular aspect of timedelta, time, date and
# datetime comparisons.
-class HarmlessMixedComparison(unittest.TestCase):
+class HarmlessMixedComparison:
# Test that __eq__ and __ne__ don't complain for mixed-type comparisons.
# Subclasses must define 'theclass', and theclass(1, 1, 1) must be a
@@ -167,7 +166,7 @@ class HarmlessMixedComparison(unittest.TestCase):
#############################################################################
# timedelta tests
-class TestTimeDelta(HarmlessMixedComparison):
+class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
theclass = timedelta
@@ -254,7 +253,7 @@ class TestTimeDelta(HarmlessMixedComparison):
self.assertRaises(TypeError, lambda: a // x)
self.assertRaises(TypeError, lambda: x // a)
- # Divison of int by timedelta doesn't make sense.
+ # Division of int by timedelta doesn't make sense.
# Division by zero doesn't make sense.
for zero in 0, 0L:
self.assertRaises(TypeError, lambda: zero // a)
@@ -514,7 +513,7 @@ class TestDateOnly(unittest.TestCase):
class SubclassDate(date):
sub_var = 1
-class TestDate(HarmlessMixedComparison):
+class TestDate(HarmlessMixedComparison, unittest.TestCase):
# Tests here should pass for both dates and datetimes, except for a
# few tests that TestDateTime overrides.
@@ -710,15 +709,16 @@ class TestDate(HarmlessMixedComparison):
def test_overflow(self):
tiny = self.theclass.resolution
- dt = self.theclass.min + tiny
- dt -= tiny # no problem
- self.assertRaises(OverflowError, dt.__sub__, tiny)
- self.assertRaises(OverflowError, dt.__add__, -tiny)
+ for delta in [tiny, timedelta(1), timedelta(2)]:
+ dt = self.theclass.min + delta
+ dt -= delta # no problem
+ self.assertRaises(OverflowError, dt.__sub__, delta)
+ self.assertRaises(OverflowError, dt.__add__, -delta)
- dt = self.theclass.max - tiny
- dt += tiny # no problem
- self.assertRaises(OverflowError, dt.__add__, tiny)
- self.assertRaises(OverflowError, dt.__sub__, -tiny)
+ dt = self.theclass.max - delta
+ dt += delta # no problem
+ self.assertRaises(OverflowError, dt.__add__, delta)
+ self.assertRaises(OverflowError, dt.__sub__, -delta)
def test_fromtimestamp(self):
import time
@@ -851,9 +851,56 @@ class TestDate(HarmlessMixedComparison):
self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
self.assertRaises(TypeError, t.strftime, 42) # arg wrong type
+ # test that unicode input is allowed (issue 2782)
+ self.assertEqual(t.strftime(u"%m"), "03")
+
# A naive object replaces %z and %Z w/ empty strings.
self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
+ #make sure that invalid format specifiers are handled correctly
+ #self.assertRaises(ValueError, t.strftime, "%e")
+ #self.assertRaises(ValueError, t.strftime, "%")
+ #self.assertRaises(ValueError, t.strftime, "%#")
+
+ #oh well, some systems just ignore those invalid ones.
+ #at least, excercise them to make sure that no crashes
+ #are generated
+ for f in ["%e", "%", "%#"]:
+ try:
+ t.strftime(f)
+ except ValueError:
+ pass
+
+ #check that this standard extension works
+ t.strftime("%f")
+
+
+ def test_format(self):
+ dt = self.theclass(2007, 9, 10)
+ self.assertEqual(dt.__format__(''), str(dt))
+
+ # check that a derived class's __str__() gets called
+ class A(self.theclass):
+ def __str__(self):
+ return 'A'
+ a = A(2007, 9, 10)
+ self.assertEqual(a.__format__(''), 'A')
+
+ # check that a derived class's strftime gets called
+ class B(self.theclass):
+ def strftime(self, format_spec):
+ return 'B'
+ b = B(2007, 9, 10)
+ self.assertEqual(b.__format__(''), str(dt))
+
+ for fmt in ["m:%m d:%d y:%y",
+ "m:%m d:%d y:%y H:%H M:%M S:%S",
+ "%z %Z",
+ ]:
+ self.assertEqual(dt.__format__(fmt), dt.strftime(fmt))
+ self.assertEqual(a.__format__(fmt), dt.strftime(fmt))
+ self.assertEqual(b.__format__(fmt), 'B')
+
def test_resolution_info(self):
self.assert_(isinstance(self.theclass.min, self.theclass))
self.assert_(isinstance(self.theclass.max, self.theclass))
@@ -957,6 +1004,7 @@ class TestDate(HarmlessMixedComparison):
# compare-by-address (which never says "equal" for distinct
# objects).
return 0
+ __hash__ = None # Silence Py3k warning
# This still errors, because date and datetime comparison raise
# TypeError instead of NotImplemented when they don't know what to
@@ -989,7 +1037,7 @@ class TestDate(HarmlessMixedComparison):
self.failUnless(self.theclass.min)
self.failUnless(self.theclass.max)
- def test_srftime_out_of_range(self):
+ def test_strftime_out_of_range(self):
# For nasty technical reasons, we can't handle years before 1900.
cls = self.theclass
self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900")
@@ -1126,6 +1174,7 @@ class TestDateTime(TestDate):
self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123")
self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123")
self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123")
+ self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123")
# str is ISO format with the separator forced to a blank.
self.assertEqual(str(t), "0002-03-02 04:05:01.000123")
@@ -1136,6 +1185,32 @@ class TestDateTime(TestDate):
# str is ISO format with the separator forced to a blank.
self.assertEqual(str(t), "0002-03-02 00:00:00")
+ def test_format(self):
+ dt = self.theclass(2007, 9, 10, 4, 5, 1, 123)
+ self.assertEqual(dt.__format__(''), str(dt))
+
+ # check that a derived class's __str__() gets called
+ class A(self.theclass):
+ def __str__(self):
+ return 'A'
+ a = A(2007, 9, 10, 4, 5, 1, 123)
+ self.assertEqual(a.__format__(''), 'A')
+
+ # check that a derived class's strftime gets called
+ class B(self.theclass):
+ def strftime(self, format_spec):
+ return 'B'
+ b = B(2007, 9, 10, 4, 5, 1, 123)
+ self.assertEqual(b.__format__(''), str(dt))
+
+ for fmt in ["m:%m d:%d y:%y",
+ "m:%m d:%d y:%y H:%H M:%M S:%S",
+ "%z %Z",
+ ]:
+ self.assertEqual(dt.__format__(fmt), dt.strftime(fmt))
+ self.assertEqual(a.__format__(fmt), dt.strftime(fmt))
+ self.assertEqual(b.__format__(fmt), 'B')
+
def test_more_ctime(self):
# Test fields that TestDate doesn't touch.
import time
@@ -1428,7 +1503,7 @@ class TestDateTime(TestDate):
def test_negative_float_fromtimestamp(self):
# Windows doesn't accept negative timestamps
- if os.name == "nt":
+ if sys.platform == "win32":
return
# The result is tz-dependent; at least test that this doesn't
# fail (like it did before bug 1646728 was fixed).
@@ -1436,7 +1511,7 @@ class TestDateTime(TestDate):
def test_negative_float_utcfromtimestamp(self):
# Windows doesn't accept negative timestamps
- if os.name == "nt":
+ if sys.platform == "win32":
return
d = self.theclass.utcfromtimestamp(-1.05)
self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000))
@@ -1456,11 +1531,12 @@ class TestDateTime(TestDate):
self.failUnless(abs(from_timestamp - from_now) <= tolerance)
def test_strptime(self):
- import time
+ import _strptime
- string = '2004-12-01 13:02:47'
- format = '%Y-%m-%d %H:%M:%S'
- expected = self.theclass(*(time.strptime(string, format)[0:6]))
+ string = '2004-12-01 13:02:47.197'
+ format = '%Y-%m-%d %H:%M:%S.%f'
+ result, frac = _strptime._strptime(string, format)
+ expected = self.theclass(*(result[0:6]+(frac,)))
got = self.theclass.strptime(string, format)
self.assertEqual(expected, got)
@@ -1488,9 +1564,9 @@ class TestDateTime(TestDate):
def test_more_strftime(self):
# This tests fields beyond those tested by the TestDate.test_strftime.
- t = self.theclass(2004, 12, 31, 6, 22, 33)
- self.assertEqual(t.strftime("%m %d %y %S %M %H %j"),
- "12 31 04 33 22 06 366")
+ t = self.theclass(2004, 12, 31, 6, 22, 33, 47)
+ self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"),
+ "12 31 04 000047 33 22 06 366")
def test_extract(self):
dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
@@ -1596,7 +1672,7 @@ class TestDateTime(TestDate):
class SubclassTime(time):
sub_var = 1
-class TestTime(HarmlessMixedComparison):
+class TestTime(HarmlessMixedComparison, unittest.TestCase):
theclass = time
@@ -1756,12 +1832,41 @@ class TestTime(HarmlessMixedComparison):
self.assertEqual(t.isoformat(), "00:00:00.100000")
self.assertEqual(t.isoformat(), str(t))
+ def test_1653736(self):
+ # verify it doesn't accept extra keyword arguments
+ t = self.theclass(second=1)
+ self.assertRaises(TypeError, t.isoformat, foo=3)
+
def test_strftime(self):
t = self.theclass(1, 2, 3, 4)
- self.assertEqual(t.strftime('%H %M %S'), "01 02 03")
+ self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004")
# A naive object replaces %z and %Z with empty strings.
self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
+ def test_format(self):
+ t = self.theclass(1, 2, 3, 4)
+ self.assertEqual(t.__format__(''), str(t))
+
+ # check that a derived class's __str__() gets called
+ class A(self.theclass):
+ def __str__(self):
+ return 'A'
+ a = A(1, 2, 3, 4)
+ self.assertEqual(a.__format__(''), 'A')
+
+ # check that a derived class's strftime gets called
+ class B(self.theclass):
+ def strftime(self, format_spec):
+ return 'B'
+ b = B(1, 2, 3, 4)
+ self.assertEqual(b.__format__(''), str(t))
+
+ for fmt in ['%H %M %S',
+ ]:
+ self.assertEqual(t.__format__(fmt), t.strftime(fmt))
+ self.assertEqual(a.__format__(fmt), t.strftime(fmt))
+ self.assertEqual(b.__format__(fmt), 'B')
+
def test_str(self):
self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004")
self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000")
@@ -1874,7 +1979,7 @@ class TestTime(HarmlessMixedComparison):
# 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 time and datetime).
-class TZInfoBase(unittest.TestCase):
+class TZInfoBase:
def test_argument_passing(self):
cls = self.theclass
@@ -2034,7 +2139,7 @@ class TZInfoBase(unittest.TestCase):
# Testing time objects with a non-None tzinfo.
-class TestTimeTZ(TestTime, TZInfoBase):
+class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
theclass = time
def test_empty(self):
@@ -2282,7 +2387,7 @@ class TestTimeTZ(TestTime, TZInfoBase):
# Testing datetime objects with a non-None tzinfo.
-class TestDateTimeTZ(TestDateTime, TZInfoBase):
+class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
theclass = datetime
def test_trivial(self):
@@ -3243,45 +3348,8 @@ class Oddballs(unittest.TestCase):
self.assertEqual(as_datetime, datetime_sc)
self.assertEqual(datetime_sc, as_datetime)
-def test_suite():
- allsuites = [unittest.makeSuite(klass, 'test')
- for klass in (TestModule,
- TestTZInfo,
- TestTimeDelta,
- TestDateOnly,
- TestDate,
- TestDateTime,
- TestTime,
- TestTimeTZ,
- TestDateTimeTZ,
- TestTimezoneConversions,
- Oddballs,
- )
- ]
- return unittest.TestSuite(allsuites)
-
def test_main():
- import gc
- import sys
-
- thesuite = test_suite()
- lastrc = None
- while True:
- test_support.run_suite(thesuite)
- if 1: # change to 0, under a debug build, for some leak detection
- break
- gc.collect()
- if gc.garbage:
- raise SystemError("gc.garbage not empty after test run: %r" %
- gc.garbage)
- if hasattr(sys, 'gettotalrefcount'):
- thisrc = sys.gettotalrefcount()
- print >> sys.stderr, '*' * 10, 'total refs:', thisrc,
- if lastrc:
- print >> sys.stderr, 'delta:', thisrc - lastrc
- else:
- print >> sys.stderr
- lastrc = thisrc
+ test_support.run_unittest(__name__)
if __name__ == "__main__":
test_main()