[Datetime-SIG] Another round on error-checking

Tim Peters tim.peters at gmail.com
Tue Sep 1 23:56:23 CEST 2015


[Alex]
>>> Here is an idea that I think may work: let's consider fold=1 instances
>>> as if they have a different tzinfo instance from the other side in both
>>> datetime subtractions and comparisons.  This will be consistent with
>>> the current stdlib and pytz work-arounds of representing "second"
>>> times using fictitious fixed-offset timezones.

[Tim]
>> That's what I was getting at by saying "fold=1 veritably _screams_
>> 'I'm no longer working in naive time'".  Which implies "I need
>> timeline arithmetic", and everything else follows from that, including
>> hash() not ignoring fold=1 either.
>>
>> But then the concept of "naive time" gets muddier:  sometimes, e.g.,
>>
>>      dt1  - dt2
>>
>> in a common zone (same tzinfo) will use classic arithmetic, but in
>> other cases (fold=1 in at least one) timeline arithmetic.

[Alex]
> I don't think this is a problem as long as we disallow mixing naive and
> aware instances in arithmetic and ordering and keep naive ≠ aware always
> rule.

"Concept gets muddier" isn't about the code, it's about the concept
getting muddier ;-)  That is, the number of brain cells needed for a
human to grasp the model, and the number of words in the docs needed
to explain it all.

Paying attention to fold=1 in naive time does muddy the naive-time
concept.  A little.  But it should hardly ever matter:  even using a
495 tzinfo, there is nothing a user working _in_ naive time can do to
see a fold=1 value.  They have to force it by hand, or use an
operation _outside_ of naive time (like .astimezone()) to get one.
Doesn't really bother me.


>> And there's also that, after
>>
>>     d = dt1 - dt2
>>
>> I suspect it may no longer always be the case that
>>
>>     dt1 == dt2 + d
>>
>> (unsure, but can't make time for it now)

> That's the price we pay for classic arithmetic anyways.

Not so.  Classic arithmetic obeys all the same friendly identities as
do, e.g., timedelta and integer arithmetic.

You gave an example in a later message, but that didn't stick to
classic arithmetic.  As soon as you mixed timezones, you went outside
of naive time, and timeline arithmetic was used in the instances of
cross-zone subtraction.  Of course the classic arithmetic identities
won't (can't always) apply to a _mix_ of classic and timeline
arithmetic.

The proposed behavior will be the first time timeline arithmetic can
be used sticking to what sure looks like "naive time" operations
(staying within a single zone).  It's the invisible fold=1 in this
case that says "not in naive time - I really want timeline
arithmetic".  I have little problem with that.  I'm just not going to
pretend it isn't _a_ change, or not _a_ muddying.


> I am not even sure we want to trigger timeline arithmetics in dt + delta expressions
> when dt.fold=1.

I am ;--)  Leaving aside that there's no sane reason to refuse to
believe a datetime _means_ fold=1 when we see it, haven't we had
enough of "unintended consequences" from trying to ignore it in other
contexts?  And carving out an exception for "oh - except fold is
ignored in datetime + timedelta, and datetime - timedelta" would be
another muddying of the newly-muddied model.  If there's isn't a solid
reason in favor of ignoring it, that would be a gratuitous muddying.


> If you do, dt - hour + hour will still not take you back because
> the seconds + hour will be classic.
>
> I don't think we can ever get rid of all paradoxes here.  Once you let your
> time go back, all bets are off.  What we can do is to shift them from one
> place to another so that you only see odd behavior when a fold=1 instance is
> involved.

I agree.  Where I go beyond is that they should _always_ see
potentially odd (to naive-time eyes) behavior when fold=1.  That's
understandable.  "Sometime yes, sometimes no" is unexplainable beyond
exhaustive listing of the "sometimes yes" and "sometimes no" cases.
Unless there's a strong reason for the distinction.


More information about the Datetime-SIG mailing list