Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Lib/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ def replace(self, year=None, month=None, day=None):
month = self._month
if day is None:
day = self._day
return date(year, month, day)
return type(self)(year, month, day)
Copy link
Member

@vstinner vstinner Oct 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer self.__class__, but I never know which one is the best :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any real preference here. I usually go with self.__class__ myself, but I was somewhat persuaded by the discussion on StackOverflow that seemed to indicate that they are equivalent in Python 3, and that type is shorter - seemed like a mixed bag as to which one is more intuitive. I'm happy to change it to the "house style".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's even a relevant precedent, since they're in two different languages, but it does seem that the C source code uses Py_TYPE(self) rather than some equivalent of self.__class__. Though for all I know that's a macro that expands to self.__class__...


# Comparisons of date objects with other.

Expand Down Expand Up @@ -1316,7 +1316,7 @@ def replace(self, hour=None, minute=None, second=None, microsecond=None,
tzinfo = self.tzinfo
if fold is None:
fold = self._fold
return time(hour, minute, second, microsecond, tzinfo, fold=fold)
return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold)

# Pickle support.

Expand Down Expand Up @@ -1597,7 +1597,7 @@ def replace(self, year=None, month=None, day=None, hour=None,
tzinfo = self.tzinfo
if fold is None:
fold = self.fold
return datetime(year, month, day, hour, minute, second,
return type(self)(year, month, day, hour, minute, second,
microsecond, tzinfo, fold=fold)

def _local_timezone(self):
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/datetimetester.py
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,13 @@ def test_replace(self):
base = cls(2000, 2, 29)
self.assertRaises(ValueError, base.replace, year=2001)

def test_subclass_replace(self):
class DateSubclass(self.theclass):
pass

dt = DateSubclass(2012, 1, 1)
self.assertIs(type(dt.replace(year=2013)), DateSubclass)

def test_subclass_date(self):

class C(self.theclass):
Expand Down Expand Up @@ -2626,6 +2633,13 @@ def test_replace(self):
self.assertRaises(ValueError, base.replace, second=100)
self.assertRaises(ValueError, base.replace, microsecond=1000000)

def test_subclass_replace(self):
class TimeSubclass(self.theclass):
pass

ctime = TimeSubclass(12, 30)
self.assertIs(type(ctime.replace(hour=10)), TimeSubclass)

def test_subclass_time(self):

class C(self.theclass):
Expand Down