osdir.com

[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
datetime-SIG.

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.