Happy New Year everyone!
I would like to start a thread here for wider feedback on my
proposal to change the return type of the addition operation
between a datetime subclass and a timedelta. Currently, adding a
timedelta to a subclass of datetime always returns a
datetime rather than an instance of the datetime subclass.
I have an open PR implementing this, PR #10902,
but I know it's a major change so I did not want to move forward
without more discussion. I first brought this up on datetime-SIG
[1], and we decided to move the discussion over here because the
people most likely to object to the change would be on this list
and not on datetime-SIG.
In addition to the datetime-SIG thread, you may find a detailed
rationale for the change in bpo-35364
[2], and a rationale for why we would want to (and arguably
already do) support subclassing datetime in bpo-32417
[3].
A short version of the strongest rationale for changing how this
works is that it is causing inconsistencies in how subclassing is
handled in alternate constructors of datetime. For a given
subclass of datetime (which I will call DateTimeSub), nearly all
alternate constructors already support subclasses correctly - DateTimeSub.fromtimestamp(x)
will return a DateTimeSub, for example. However, because
DateTimeSub + timedelta returns datetime, any alternate
constructor implemented in terms of timedelta additions will leak
that implementation detail by returning a datetime object instead
of the subclass. The biggest problem is that datetime.fromutc
is defined in terms of timedelta addition, so DateTimeSub.now()
returns a DateTimeSub object, but DateTimeSub.now(timezone.utc)
returns a datetime object! This is one of the most annoying things
to work around when building a datetime subclass, and I don't know
of any situation where someone wants their subclass to be
lost on addition with a timedelta.
From my understanding, this has been discussed before and the original objection was that this implementation assumes that the datetime subclass has a constructor with the same (or a sufficiently similar) signature as datetime. This may be a legitimate gripe, but unfortunately that ship has sailed long ago. All of datetime's alternate constructors make this assumption. Any subclass that does not meet this requirement must have worked around it long ago (or they don't care about alternate constructors).
Thanks for your attention, I look forward to your replies.
Best,
Paul
[2] https://bugs.python.org/issue35364#msg331065
[3] https://bugs.python.org/issue32417#msg331353