New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tests fail in 2038 #56
Comments
still there in DateTime-5.4 |
@d-maurer Do have an idea what's going wrong here? |
Michael Howitz wrote at 2024-3-19 00:24 -0700:
@d-maurer Do have an idea what's going wrong here?
`DateTime` uses a `float` in its state representation (representing
seconds since the epoch).
A `float` has limited precision. This limited precision is the cause
of the error as demontrated by the following transscript:
```pyconsole
>> from DateTime import DateTime
>> f=DateTime()
>> f.__setstate__((2198556426.235027, False, 'GMT+1'))
>> f
DateTime('2039/09/02 07:07:6.235027 GMT+1')
>> f.__getstate__()
(2198556426.235026, False, 'GMT+1')
```
As we see, the `__getstate__` result has lost the last bit.
If we want to get rid of errors like this, we must avoid
a `float` in the `__getstate__` representation.
One possibility would be to replace the `float` by a
pair "(integral) seconds since epoch", "remaining microseconds".
Another one to replace the `float` by
"microseconds since the epoch".
to use
|
For reference: DateTime/src/DateTime/DateTime.py Lines 448 to 468 in e892a9d
this was set as a float to have shorter pickles, this was apparently wrong for this reason. In our case ( cc @fdiary ), we considered that it is wrong because of the precision loss and we are using a monkey patch to export the int in Unlike with protocol 1, a float is no longer serialized shorter pickle than an int with pickle protocol 3: >>> pickletools.dis(pickle.dumps(2198556426.235026, 3))
0: \x80 PROTO 3
2: G BINFLOAT 2198556426.235026
11: . STOP
highest protocol among opcodes = 2
>>> pickletools.dis(pickle.dumps(int(2198556426.235026 * 1000000.0), 3))
0: \x80 PROTO 3
2: \x8a LONG1 2198556426235026
11: . STOP
highest protocol among opcodes = 2 for the fix, I think we can consider exporting the int "as is" during |
Jérome Perrin wrote at 2024-3-19 04:36 -0700:
...
for the fix, I think we can consider exporting the int "as is" during `__getstate__` and add more conditions during the `__setstate__` to support the new format.
I assume this `int` represents "microseconds since epoch`.
In this case, would you like to prepare a PR (as you apparently
have already most of the code for it).
|
exactly: DateTime/src/DateTime/DateTime.py Lines 861 to 865 in 868de71
I submitted #62 with this change we discussed. I tried to run osc myself but I had errors when trying to create an account, @bmwiedemann can you try easily from the linked PR ? |
looks good in a quick test. |
During pickle serialization, the `_micros` attribute was casted to float, to save a little bit of disk space by making shorter pickles, this was true when ZODB was using pickle protocol 1, but nowadays it uses protocol 3 and exporting as an int produces pickles of the same length as with a float. Fixes #56 Co-authored-by: Dieter Maurer <d-maurer@users.noreply.github.com>
Fix released in https://pypi.org/project/DateTime/5.5/ |
BUG/PROBLEM REPORT / FEATURE REQUEST
What I did:
What I expect to happen:
tests should keep working in the future (at least 16 years)
What actually happened:
similar to issue #41 in that there is a rounding error in
DateTime-5.2
that can randomly break a test.What version of Python and Zope/Addons I am using:
openSUSE-Tumbleweed-20230729 python3.10
The text was updated successfully, but these errors were encountered: