Datetime changes in Python 4.0
Have you heard about the upcoming datetime
library changes in Python 4? It’s pretty significant because it’s the first notable backward incompatible change in the next major Python version since the whole py2 to py3 transition, and it’s likely to require changes to most of the Python programs during upgrade.
Rationale
The core Python team, given how long it took to deprecate py2, wasn’t exactly happy to do such a transition, and the topic was generally controversial whenever it came up (see this thread for example). Still, they eventually had to agree that the current implementation of datetime
does more damage than it's supposed to, and that the design problems with it are fundamental and cannot be fixed in a backwards compatible way without nasty edge cases — all due to the way relativity works and how it doesn't agree with naive interpretation of time.
The PEP quote sums it up best:
Rejected ideas
The idea to publish the corrected
datetime
package as a separatereldatetime
package was initially considered, but after a long debate, it was deemed impractical. The scientific community is a core user group for Python and we should ensure that Python remains a viable option for their use case. It ultimately seems morally wrong to expect this group to switch between two different datetime implementations because of a fundamental architecture error in default implementation. This justifies a backwards incompatible change.
Summary of changes
This code works perfectly now on Python 3.9…
>>> a = datetime(2001, 2, 3, 4, 5, 6, 789, tzinfo=pytz.tzinfo("Europe/Paris"))
>>> b = datetime(2001, 12, 13, 14, 56, 7, tzinfo=pytz.tzinfo("Europe/Warsaw"))
>>> a == b
False
>>> a < b
True
but on Python 4.0, once launched, it will produce the following output:
>>> a = datetime(2001, 2, 3, 4, 5, 6, 789, tzinfo=pytz.tzinfo("Europe/Paris"))
>>> b = datetime(2001, 12, 13, 14, 56, 7, tzinfo=pytz.tzinfo("Europe/Warsaw"))
>>> a == b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RelativisticError: 'datetime.datetime' objects cannot be compared without a frame of reference
This reflects the physical fact that two events cannot be considered “simultaneous” unless we consider a particular frame of reference. In fact, depending on the frame of reference you establish, event A can occur before or after event B.
To avoid such ambiguity, the code has to be rewritten to:
>>> with datetime.relativistic.FrameOfReference("Earth"):
... a == b
...
False
The new relativistic
module contains the new RelativisticError
exception as well as a set of standard frames of reference (including the centre of Earth, the Sun and the Milky Way). Third party libraries similar to pytz
will follow to provide additional FrameOfReference
implementations to cater for advanced scientific use cases.
That’s the gist, and of course please read the PEP for the rationale and all the interesting implementation details.
2021–04–02 update: This article is parody. I would like to thank all the readers for celebrating April 1st together!