pint icon indicating copy to clipboard operation
pint copied to clipboard

pint 0.19.1 breaks pickled Quantities stored with 0.18

Open joernu76 opened this issue 2 years ago • 5 comments

We use pickle to store some test data. After upgrading to pint=0.19.1, we get the following error:

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <[AttributeError('_d') raised in repr()] UnitsContainer object at 0x7f2cc4816680>
state = ({'degrees_east': 1}, 2910532461319600299, 1, <class 'float'>)
    def __setstate__(self, state):
>       self._d, self._one, self._non_int_type = state
E       ValueError: too many values to unpack (expected 3)
/opt/conda/lib/python3.9/site-packages/pint/util.py:429: ValueError

This can be reproduced with a simple test case containing a "1K" variable. This string represents a serialisation of "10K" via 0.18:

a=b'\x80\x04\x95\x9b\x00\x00\x00\x00\x00\x00\x00\x8c\x04pint\x94\x8c\x12_unpickle_quantity\x94\x93\x94\x8c\rpint.quantity\x94\x8c\x08Quantity\x94\x93\x94K\n\x8c\tpint.util\x94\x8c\x0eUnitsContainer\x94\x93\x94)\x81\x94(h\x06\x8c\x05udict\x94\x93\x94)\x81\x94\x8c\x06kelvin\x94K\x01sNK\x01\x8c\x08builtins\x94\x8c\x05float\x94\x93\x94t\x94b\x87\x94R\x94.'

With 0.19.1, loading pickle.loads this error is given:

In [6]: pickle.loads(a)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [6], in <module>
----> 1 pickle.loads(a)

File /opt/anaconda3/lib/python3.9/site-packages/pint/util.py:429, in UnitsContainer.__setstate__(self, state)
    428 def __setstate__(self, state):
--> 429     self._d, self._one, self._non_int_type = state
    430     self._hash = None

ValueError: too many values to unpack (expected 3)
```.

joernu76 avatar Apr 10 '22 18:04 joernu76

This can be traced back to this change https://github.com/hgrecco/pint/commit/19c9d326975e2255c2ea51aed8d1be2ae8f7d579 Seemingly it is missing in the CHANGES "breaking change" section?

joernu76 avatar Apr 10 '22 18:04 joernu76

Just to clarify: Are you having problems pickling and unpickling data in general, or problems unpickling data that has been pickled with an older version?

hgrecco avatar Apr 10 '22 20:04 hgrecco

I have problems unpickling data with 0.19 that was pickled with 0.18. This may not be a "bug" per se, but it is a "breaking change" for me.

I am also interested in having an easy way to "upgrade" my testdata-pickles to the new format.

joernu76 avatar Apr 11 '22 06:04 joernu76

I think, I could try creating a merge request that'd be "backwards-compatible" when reading in pickles. Would you be interested in that?

joernu76 avatar Apr 18 '22 07:04 joernu76

Indeed!

hgrecco avatar Apr 18 '22 19:04 hgrecco

We should add this in the CHANGELOG under 0.19 version as breaking change

jules-ch avatar Nov 24 '22 23:11 jules-ch

Still seeing this bug with pint 0.21.1. Curious why it was closed? On our project we are contemplating pinning the pint version to 0.18 to avoid this issue - not my favorite solution. Is the 'right way' to re-create any old pickled Quantities with a newer version of pint?

whoburg avatar Sep 24 '23 18:09 whoburg

@whoburg Exactly, pickle is a format for serializing and de-serializing a Python object structure. If the structure change, a certain pickle file could become obsolete. I would be happy to show you how to reconvert the files. Please share one with me

hgrecco avatar Sep 24 '23 18:09 hgrecco

Understood. Thanks @hgrecco

whoburg avatar Sep 26 '23 03:09 whoburg