Skip to content

Commit f568218

Browse files
committed
Issue #6641: Original commit for this issue, r82053, introduced a
regression making datetime subclass' strptime return datetime rather than subclass instances. Fixed this bug and a few typos.
1 parent 49d7a57 commit f568218

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

Lib/_strptime.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from re import IGNORECASE, ASCII
1818
from re import escape as re_escape
1919
from datetime import (date as datetime_date,
20-
datetime as datetime_datetime,
2120
timedelta as datetime_timedelta,
2221
timezone as datetime_timezone)
2322
try:
@@ -297,7 +296,7 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
297296

298297

299298
def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
300-
"""Return a 2-tuple consisting of a time struct and an int containg
299+
"""Return a 2-tuple consisting of a time struct and an int containing
301300
the number of microseconds based on the input string and the
302301
format string."""
303302

@@ -483,8 +482,8 @@ def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"):
483482
tt = _strptime(data_string, format)[0]
484483
return time.struct_time(tt[:9])
485484

486-
def _strptime_datetime(data_string, format="%a %b %d %H:%M:%S %Y"):
487-
"""Return a datetime instace based on the input string and the
485+
def _strptime_datetime(class_, data_string, format="%a %b %d %H:%M:%S %Y"):
486+
"""Return a class_ instance based on the input string and the
488487
format string."""
489488
tt, fraction = _strptime(data_string, format)
490489
gmtoff, tzname = tt[-2:]
@@ -497,4 +496,4 @@ def _strptime_datetime(data_string, format="%a %b %d %H:%M:%S %Y"):
497496
tz = datetime_timezone(tzdelta)
498497
args += (tz,)
499498

500-
return datetime_datetime(*args)
499+
return class_(*args)

Lib/test/test_datetime.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,8 +1100,13 @@ def strftime(self, format_spec):
11001100
self.assertEqual(b.__format__(fmt), 'B')
11011101

11021102
def test_resolution_info(self):
1103-
self.assertIsInstance(self.theclass.min, self.theclass)
1104-
self.assertIsInstance(self.theclass.max, self.theclass)
1103+
# XXX: Should min and max respect subclassing?
1104+
if issubclass(self.theclass, datetime):
1105+
expected_class = datetime
1106+
else:
1107+
expected_class = date
1108+
self.assertIsInstance(self.theclass.min, expected_class)
1109+
self.assertIsInstance(self.theclass.max, expected_class)
11051110
self.assertIsInstance(self.theclass.resolution, timedelta)
11061111
self.assertTrue(self.theclass.max > self.theclass.min)
11071112

@@ -1732,9 +1737,11 @@ def test_strptime(self):
17321737

17331738
string = '2004-12-01 13:02:47.197'
17341739
format = '%Y-%m-%d %H:%M:%S.%f'
1735-
expected = _strptime._strptime_datetime(string, format)
1740+
expected = _strptime._strptime_datetime(self.theclass, string, format)
17361741
got = self.theclass.strptime(string, format)
17371742
self.assertEqual(expected, got)
1743+
self.assertIs(type(expected), self.theclass)
1744+
self.assertIs(type(got), self.theclass)
17381745

17391746
strptime = self.theclass.strptime
17401747
self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE)
@@ -1896,6 +1903,12 @@ def newmeth(self, start):
18961903
self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month +
18971904
dt1.second - 7)
18981905

1906+
class TestSubclassDateTime(TestDateTime):
1907+
theclass = SubclassDatetime
1908+
# Override tests not designed for subclass
1909+
def test_roundtrip(self):
1910+
pass
1911+
18991912
class SubclassTime(time):
19001913
sub_var = 1
19011914

Modules/datetimemodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4377,8 +4377,8 @@ datetime_strptime(PyObject *cls, PyObject *args)
43774377
if(module == NULL)
43784378
return NULL;
43794379
}
4380-
return PyObject_CallMethod(module, "_strptime_datetime", "uu",
4381-
string, format);
4380+
return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4381+
cls, string, format);
43824382
}
43834383

43844384
/* Return new datetime from date/datetime and time arguments. */

0 commit comments

Comments
 (0)