Result of adding timedelta with datetime
I would like to call your attention to my PR #10902 making timedelta addition respect the subclass of the object it was added to: https://github.com/python/cpython/pull/10902 Because date and datetime have their classes hard-coded into their __add__ methods, any datetime arithmetic /discards/ the subclass. Since datetime arithmetic is a very common primitive in datetime operations, this leads to all kinds of funky behaviors like the fact that DatetimeSubclass.fromtimestamp(0) returns a DatetimeSubclass (as it should), but DatetimeSubclass.fromtimestamp(0, timezone.utc) returns a datetime. I think that this is the right behavior (I have a more detailed rationale here: https://bugs.python.org/issue35364#msg331065 ) and I find it unlikely that there will be any significant bugs introduced by this change except in very strange edge cases. I know that changing return types like this can be seen as a major change (I do not, for example, suggest backporting this before 3.8), so I am bringing it up here to get some extra discussion on the matter. Thanks, Paul
making timedelta addition respect the subclass of the object it was added to
I tried to fight this battle 10 years ago and I lost. See < https://bugs.python.org/issue2267>. The main argument is that the """base class has no idea what requirements may exist for invoking a subclass's constructor""" All python types behave this way: int, float, lists. On Fri, Dec 7, 2018 at 10:16 AM Paul Ganssle <paul@ganssle.io> wrote:
I would like to call your attention to my PR #10902 making timedelta addition respect the subclass of the object it was added to: https://github.com/python/cpython/pull/10902
Because date and datetime have their classes hard-coded into their __add__ methods, any datetime arithmetic *discards* the subclass. Since datetime arithmetic is a very common primitive in datetime operations, this leads to all kinds of funky behaviors like the fact that DatetimeSubclass.fromtimestamp(0) returns a DatetimeSubclass (as it should), but DatetimeSubclass.fromtimestamp(0, timezone.utc) returns a datetime.
I think that this is the right behavior (I have a more detailed rationale here: https://bugs.python.org/issue35364#msg331065 ) and I find it unlikely that there will be any significant bugs introduced by this change except in very strange edge cases. I know that changing return types like this can be seen as a major change (I do not, for example, suggest backporting this before 3.8), so I am bringing it up here to get some extra discussion on the matter.
Thanks,
Paul _______________________________________________ Datetime-SIG mailing list -- datetime-sig@python.org To unsubscribe send an email to datetime-sig-leave@python.org https://mail.python.org/mailman3/lists/datetime-sig.python.org/ The PSF Code of Conduct applies to this mailing list: https://www.python.org/psf/codeofconduct/
That is a good point to consider, but even if it is a major concern, I am not sure it leaves us much worse off than the current situation. Consider that for anyone to implement their own datetime subclass that actually survives any of these operations, they must implement __add__, __radd__ and a bunch of other functions themselves anyway. /If/ they have an incompatible constructor /and/ their implementation of __add__ currently looks like this: def __add__(self, other): dt = super().__add__(other) return type(self).fromdatetime(dt) Then this change will indeed break addition for them. It would require them to change their implementation to something like: def __add__(self, other): dt = self.todatetime() + other return type(self).fromdatetime(dt) or some variation on the logic that exists in CPython. That said, we /already/ make the assumption that calling the subclass constructor just works in several places. It's used in replace and every alternate constructor. This change would just make timedelta addition consistent with all the other alternate constructors. The only people who should be affected by it are people who create a subclass that has a different signature for their constructor but don't use /any/ of the existing alternate constructors, but /do/ make use of timedelta addition. I think it's a pretty safe change to make. I am happy to bring this to Python-Dev if the people opposed to this change are not on datetime-sig. On 12/7/18 1:29 PM, Alexander Belopolsky wrote:
making timedelta addition respect the subclass of the object it was added to
I tried to fight this battle 10 years ago and I lost. See <https://bugs.python.org/issue2267>.
The main argument is that the """base class has no idea what requirements may exist for invoking a subclass's constructor"""
All python types behave this way: int, float, lists.
On Fri, Dec 7, 2018 at 10:16 AM Paul Ganssle <paul@ganssle.io <mailto:paul@ganssle.io>> wrote:
I would like to call your attention to my PR #10902 making timedelta addition respect the subclass of the object it was added to: https://github.com/python/cpython/pull/10902
Because date and datetime have their classes hard-coded into their __add__ methods, any datetime arithmetic /discards/ the subclass. Since datetime arithmetic is a very common primitive in datetime operations, this leads to all kinds of funky behaviors like the fact that DatetimeSubclass.fromtimestamp(0) returns a DatetimeSubclass (as it should), but DatetimeSubclass.fromtimestamp(0, timezone.utc) returns a datetime.
I think that this is the right behavior (I have a more detailed rationale here: https://bugs.python.org/issue35364#msg331065 ) and I find it unlikely that there will be any significant bugs introduced by this change except in very strange edge cases. I know that changing return types like this can be seen as a major change (I do not, for example, suggest backporting this before 3.8), so I am bringing it up here to get some extra discussion on the matter.
Thanks,
Paul
_______________________________________________ Datetime-SIG mailing list -- datetime-sig@python.org <mailto:datetime-sig@python.org> To unsubscribe send an email to datetime-sig-leave@python.org <mailto:datetime-sig-leave@python.org> https://mail.python.org/mailman3/lists/datetime-sig.python.org/ The PSF Code of Conduct applies to this mailing list: https://www.python.org/psf/codeofconduct/
I am happy to bring this to Python-Dev if the people opposed to this change are not on datetime-sig.
I think you should. As much as I am on your side here, I don't want datetime classes to become special snowflakes in the Python type system. So far all arguments in favor of retaining the type of datetime subclasses in arithmetic operations apply equally to the other Python types. BTW, Tim's original datetime.py prototype used type(self) in arithmetic operations, but it was later changed in order to match C.
participants (2)
-
Alexander Belopolsky
-
Paul Ganssle