Paul Ganssle <p.gans...@gmail.com> added the comment:

> This is not easy problem, ant it doesn't have right solution. Different 
> decisions were made for the result type of alternate constructors and 
> operators for different classes.

It's certainly true that it occasionally makes sense to do something like this, 
but this one is particularly egregious. Because of an implementation detail of 
`fromtimestamp` (and `now`, and a few others), which is actually relying on an 
implementation detail of `fromutc`, which is actually relying on what *may* 
have been a choice in the `__add__` method of timedelta, you get a *different 
class* in the alternate constructor of a subclass depending on the *argument* 
to the alternate constructor. This is pretty solidly a bug.

I think the things we need to take into account are:

1. What do we consider the contract of the relevant functions involved
2. What do people expect the code to do?
3. Is it likely that anyone is *relying* on the existing behavior.


The most fundamental problem, timedelta addition, is also the closest call, so 
I think we should *start* with the analysis there.

For #1, the contract is either "x + timedelta returns a datetime if x is a 
datetime subclass" or "x + timedelta returns a datetime or datetime subclass" - 
both of these are consistent with the current behavior, and as long as 
"datetime subclass isa datetime", I don't see that there would be anything 
fundamentally backwards-incompatible about changing what is actually returned.

For #2, I think people almost universally consider it a bug or at the very 
least counter-intuitive that `DatetimeSubclass + timedelta` returns a datetime 
and not a DatetimeSubclass. There are many instances of people who create 
datetime subclasses like arrow and pendulum (for just two OSS examples) - all 
of them end up with fairly complicated implementations where they have to work 
around all the places where the underlying implementation has hard-coded 
datetime. Some of these have been fixed already, but it's a notorious game of 
whack-a-mole. I've never heard of a situation where someone *wants* the other 
behavior.

For #3, it is feasible that there are people who are accidentally relying on 
this behavior, but it would only be in pretty unpythonic code (like assert 
type(dt) == datetime), or when using broken datetime subclasses. The only 
situation where I can think of where this behavior might be desirable is if you 
have a thin datetime wrapper that only needs to be the wrapper class at the 
point of input, and afterwards you don't care what class it is (and as such 
you'd want it to be datetime, so as to take advantage of the fast paths in C 
code). That is far from the common case, and it's a "nice to have" - if it 
doesn't happen you'll get slower code, not broken code, and you can fix it the 
same way everyone else fixes their broken subclasses by overriding __add__ and 
__radd__.

I think there is a pretty compelling case for switching timedelta + 
datetimesubclass over to returning `datetimesubclass`.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue35364>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to