diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 728a9dc855d..a30cb86eca7 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -17,7 +17,6 @@ from re import compile as re_compile from re import IGNORECASE, ASCII from re import escape as re_escape from datetime import (date as datetime_date, - datetime as datetime_datetime, timedelta as datetime_timedelta, timezone as datetime_timezone) try: @@ -297,7 +296,7 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): - """Return a 2-tuple consisting of a time struct and an int containg + """Return a 2-tuple consisting of a time struct and an int containing the number of microseconds based on the input string and the format string.""" @@ -483,8 +482,8 @@ def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"): tt = _strptime(data_string, format)[0] return time.struct_time(tt[:9]) -def _strptime_datetime(data_string, format="%a %b %d %H:%M:%S %Y"): - """Return a datetime instace based on the input string and the +def _strptime_datetime(class_, data_string, format="%a %b %d %H:%M:%S %Y"): + """Return a class_ instance based on the input string and the format string.""" tt, fraction = _strptime(data_string, format) gmtoff, tzname = tt[-2:] @@ -497,4 +496,4 @@ def _strptime_datetime(data_string, format="%a %b %d %H:%M:%S %Y"): tz = datetime_timezone(tzdelta) args += (tz,) - return datetime_datetime(*args) + return class_(*args) diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index b320e1f8029..42c18e69531 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -1100,8 +1100,13 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): self.assertEqual(b.__format__(fmt), 'B') def test_resolution_info(self): - self.assertIsInstance(self.theclass.min, self.theclass) - self.assertIsInstance(self.theclass.max, self.theclass) + # XXX: Should min and max respect subclassing? + if issubclass(self.theclass, datetime): + expected_class = datetime + else: + expected_class = date + self.assertIsInstance(self.theclass.min, expected_class) + self.assertIsInstance(self.theclass.max, expected_class) self.assertIsInstance(self.theclass.resolution, timedelta) self.assertTrue(self.theclass.max > self.theclass.min) @@ -1732,9 +1737,11 @@ class TestDateTime(TestDate): string = '2004-12-01 13:02:47.197' format = '%Y-%m-%d %H:%M:%S.%f' - expected = _strptime._strptime_datetime(string, format) + expected = _strptime._strptime_datetime(self.theclass, string, format) got = self.theclass.strptime(string, format) self.assertEqual(expected, got) + self.assertIs(type(expected), self.theclass) + self.assertIs(type(got), self.theclass) strptime = self.theclass.strptime self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE) @@ -1896,6 +1903,12 @@ class TestDateTime(TestDate): self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + dt1.second - 7) +class TestSubclassDateTime(TestDateTime): + theclass = SubclassDatetime + # Override tests not designed for subclass + def test_roundtrip(self): + pass + class SubclassTime(time): sub_var = 1 diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index ed045205fe7..ddb5a054cfb 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -4377,8 +4377,8 @@ datetime_strptime(PyObject *cls, PyObject *args) if(module == NULL) return NULL; } - return PyObject_CallMethod(module, "_strptime_datetime", "uu", - string, format); + return PyObject_CallMethod(module, "_strptime_datetime", "Ouu", + cls, string, format); } /* Return new datetime from date/datetime and time arguments. */