-
-
Notifications
You must be signed in to change notification settings - Fork 32.7k
bpo-31222: Make (datetime|date|time).replace return subclass type in Pure Python #4176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. Thanks again to your contribution and we look forward to looking at it! |
I'll note that since there's no actual behavior change for the delivered binaries, it's not clear whether this requires a NEWS entry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I have a few comments.
@@ -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) |
There was a problem hiding this comment.
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 :-)
There was a problem hiding this comment.
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".
There was a problem hiding this comment.
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__
...
Lib/test/datetimetester.py
Outdated
@@ -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 C(self.theclass): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind to rename the class to "DateSubclass" or anything longer than a single letter? :-) Same request for the class below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have particularly strong opinions on the naming here, I mainly used C
because test_subclass_date
and test_subclass_time
both use C
as their "in-function subclass", and there are already top-level SubclassTime
/SubclassDate
/SubclassDatetime
classes that are used to run all or nearly all the tests again on a subclass (presumably to check that subclasses satisfy the same contract as the base class). I think DateSubclass
might get confused with these other test classes.
Another alternative which avoids this question entirely is to replace the specific test_subclass_replace
function with a test_replace_class
function (which will automatically get the subclass check by virtue of the inheritance through TestSubclassDateTime
). The main reasons I didn't do this are that 1. I think the logic is a bit clearer (why are you checking that .replace
returns the same class as the object?) and 2. this way it automatically "recurses" the check such that it's clear that even subclasses retain this property. This is a fairly weakly-held opinion, though, and I'm willing to be changed.
If we do decide that renaming is best, would maybe _Subclass
be a reasonable name?
I updated the subclass names to be somewhat more descriptive. The only remaining question is whether this needs a news item. |
Lib/test/datetimetester.py
Outdated
@@ -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): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove "_" prefix in class names. These classes are only defined in the scope of the test, no need to declare them as "private" with the "_" prefix.
0615f2b
to
052302d
Compare
052302d
to
8f26dd3
Compare
This should be ready to go - any thoughts on whether it needs NEWS? |
I merged your PR, thanks! |
…Pure Python (pythonGH-4176) (cherry picked from commit 191e993)
GH-4356 is a backport of this pull request to the 3.6 branch. |
Per the discussion on the issue tracker, the behavior of the pure python implementation of
datetime
,date
andtime
are out of whack with the equivalent from_datetimemodule.c
. Since the C version is almost certainly what's being used almost everywhere, this shouldn't have any real behavioral changes. The equivalent bug inpypy3
has been fixed for some time.https://bugs.python.org/issue31222