[Datetime-SIG] Another round on error-checking

Tim Peters tim.peters at gmail.com
Mon Aug 31 22:03:19 CEST 2015

>>>     def __hash__(self):
>>>         if self._hashcode == -1:
>>>             tzoff = self.utcoffset()
>>>             if tzoff is None:
>>>                 self._hashcode =
>>> hash(self.replace(first=True)._getstate()[0])
>>>             else:
>>>                 days = _ymd2ord(self.year, self.month, self.day)
>>>                 seconds = self.hour * 3600 + self.minute * 60 +
>>> self.second
>>>                 self._hashcode = hash(timedelta(days, seconds,
>>> self.microsecond) - tzoff)
>>>         return self._hashcode

> ...
> I think I admitted defeat too soon.  Can you present a specific case where
> "two datetimes that compare true have different hashes"?

Two aware datetimes in a single zone representing the earlier and
later ambiguous time.  All fields (including tzinfo) are identical
except for fold.  "==" says True.  But `tzoff` differs between them,
so the code above passes different values to `hash()`.  It's not
guaranteed that the hashes differ, but it's very likely they differ.

> There may be some subtlety due to the fact that we ignore tzinfo in ==
> if it is the same for both sides,

That's why they compare equal in this case.

> but when we compute hash(), we don't know what's on the other
> side.  It is hard to tell without a specific example.  I thought I got it
> right when I wrote the code above, but it is possible I missed some case.

It's a puzzle ;-)

More information about the Datetime-SIG mailing list