[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] Return type of datetime subclasses added to timedelta

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
<https://github.com/python/cpython/pull/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
<https://mail.python.org/archives/list/datetime-sig at python.org/thread/TGB3VZS5EKM4R2VFUA44323FZFRN2DSJ/>
[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

In addition to the datetime-SIG thread, you may find a detailed
rationale for the change in bpo-35364
<https://bugs.python.org/issue35364#msg331065> [2],? and a rationale for
why we would want to (and arguably already /do/) support subclassing
datetime in bpo-32417 <https://bugs.python.org/issue32417#msg331353> [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.