[Datetime-SIG] Another round on error-checking

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


[Alex]
> I think the main difference between Tim's current proposal and what was
> previously discussed is that all older proposals somehow required  a third
> value for fold.   Note that there is a third variant suggested by Guido
> off-list and discussed in the PEP:  have fold=-1 by default, ignore it
> unless it is nonnegative and design whatever you want for fold=0/1 without
> concerns for backward compatibility.   This effectively will give two
> different datetime classes: classic and new.  Both are perfectly consistent,
> but if you think interoperation between naive and aware is confusing, try to
> explain how new naive instances will interoperate with classic aware!

It's worth some thought.  I don't think interoperation between naive
and aware now is confusing at all.  It's usually just plain forbidden;
e.g.,

>>> import datetime
>>> x = datetime.datetime.now()  # naive
>>> y = x.replace(tzinfo=datetime.timezone.utc) # aware

>>> x < y
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    x < y
TypeError: can't compare offset-naive and offset-aware datetimes

>>> x - y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    x - y
TypeError: can't subtract offset-naive and offset-aware datetimes

>>> x == y
False

Only that last one may be surprising, but it's really just another way
of saying "naive and aware don't mix, period".  Do you have other
kinds of interoperation in mind?

Presumably a similarly high wall would be erected between fold < 0 and
fold >= 0 instances.

If this were pursued then, e.g., the seemingly intractable problem
with __hash__() would go away (no more reason to _try_ to ignore fold
>= 0), and, e.g., for an aware dt then dt.replace(fold=1) -
dt.replace(fold=0) could return the expected result when dt specified
an ambiguous time (ditto:  no more reason to try to ignore fold==1),
and likewise for comparing those values.

I can see one kind of annoyance that would remain:

    dt2 = dt1 + a_timedelta

is currently specified to force dt2.fold==0 even if dt1.fold==1.  But
that may not make good sense.  There's no way to know whether adding
`a_timedelta` takes dt1 out of a fold without doing timeline
arithmetic.

The conceptual mess in my head is that "fold=1" screams "I'm no longer
in naive time", but "fold=0" does not (where "in naive time" means
classic arithmetic is appropriate, and "not in naive time" means
timeline arithmetic is appropriate - while fold < 0 would be an
explicit way to say "in naive time", it's unclear that "fold >= 0"
should always mean "not in naive time", despite that fold=1 makes no
sense in naive time).

At least it's all clear now ;-)


More information about the Datetime-SIG mailing list