PEP 495: Restore the transitivity of == comparisons.

This commit is contained in:
Alexander Belopolsky 2015-09-12 23:23:39 -04:00
parent 2f46d104f0
commit e2f6146f36
1 changed files with 75 additions and 14 deletions

View File

@ -397,27 +397,86 @@ according to the following table:
where ``delta`` is the size of the fold or the gap.
Temporal Arithmetic
===================
Temporal Arithmetic and Comparison Operators
============================================
The value of "fold" will be ignored in all operations except those
that involve conversion between timezones. [#]_ As a consequence,
The value of the ``fold`` attribute will be ignored in all operations
with naive datetime instances. As a consequence, naive
``datetime.datetime`` or ``datetime.time`` instances that differ only
by the value of ``fold`` will compare as equal. Applications that
need to differentiate between such instances should check the value of
``fold`` or convert them to a timezone that does not have ambiguous
times.
``fold`` explicitly or convert those instances to a timezone that does
not have ambiguous times.
The result of addition (subtraction) of a timedelta to (from) a
datetime will always have ``fold`` set to 0 even if the
The value of ``fold`` will also be ignored whenever a timedelta is
added to or subtracted from a datetime instance which may be either
aware or naive. The result of addition (subtraction) of a timedelta
to (from) a datetime will always have ``fold`` set to 0 even if the
original datetime instance had ``fold=1``.
.. [#] Computing a difference between two aware datetime instances
with different values of ``tzinfo`` involves an implicit timezone
conversion. In this case, the result may depend on the value of
the ``fold`` attribute in either of the instances, but only if the
instance has ``tzinfo`` that accounts for the value of ``fold``
in its ``utcoffset()`` method.
No changes are proposed to the way the difference ``t - s`` is
computed for datetime instances ``t`` and ``s``. If both instances
are naive or ``t.tzinfo`` is the same instance as ``s.tzinfo``
(``t.tzinfo is s.tzinfo`` evaluates to ``True``) then ``t - s`` is a
timedelta ``d`` such that ``s + d == t``. As explained in the
previous paragraph, timedelta addition ignores both ``fold`` and
``tzinfo`` attributes and so does intra-zone or naive datetime
subtraction.
Naive and intra-zone comparisons will ignore the value of ``fold`` and
return the same results as they do now.
The inter-zone subtraction will be defined as it is now: ``t - s`` is
computed as ``(t - t.utcoffset()) - (s -
s.utcoffset()).replace(tzinfo=t.tzinfo)``, but the result may now
depend on the values of ``t.fold`` and ``s.fold`` when either
``t.tzinfo`` or ``s.tzinfo`` is post-PEP. [#]_
.. [#] Note that the new rules may result in a paradoxical situation
when ``s == t`` but ``s - t != timedelta(0)``. Such paradoxes are
not really new and are inherent in the overloading of the minus
operator as two different intra- and inter-zone operations. For
example, one can easily construct datetime instances ``t`` and ``s``
with some variable offset ``tzinfo`` and a datetime ``u`` with
``tzinfo=timezone.utc`` such that ``(t - u) - (s - u) != t - s``.
The explanation for this paradox is that the minuses inside the
parentheses and the two other minuses are really three different
operations: inter-zone datetime subtraction, timedelta subtraction
and intra-zone datetime subtraction which have the mathematical
properties of subtraction separately, but not when combined in a
single expression.
Aware datetime Equality Comparison
----------------------------------
The aware datetime comparison operators will work the same as they do
now with results indirectly affected by the value of ``fold`` whenever
``utcoffset()`` value of one of the operands depends on it, with one
exception. Whenever one of the operands in inter-zone comparison is
such that its ``utcoffset()`` depends on the value of its ``fold``
fold attribute, the result is ``False``. [#]_
.. [#] This exception is designed to preserve the hash and equivalence
invariants in the face of paradoxes of inter-zone arithmetic.
Formally, ``t == s`` when ``t.tzinfo is s.tzinfo`` evaluates to
``False`` can be defined as follows. Let ``toutc(t, fold)`` be a
function that takes an aware datetime instance ``t`` and returns a
naive instance representing the same time in UTC assuming a given
value of ``fold``:
.. code::
def toutc(t, fold):
u = t - t.replace(fold=fold).utcoffset()
return u.replace(tzinfo=None)
Then ``t == s`` is equivalent to
.. code::
toutc(t, fold=0) == toutc(t, fold=1) == toutc(s, fold=0) == toutc(s, fold=1)
Backward and Forward Compatibility
@ -725,3 +784,5 @@ This image is a work of a U.S. military or Department of Defense
employee, taken or made as part of that person's official duties. As a
work of the U.S. federal government, the image is in the public
domain.
LocalWords: isdst Py tm