Skip to content
Advertisement

Python 3.9: unpickling of IsoCalendarDate data returns a tuple

Consider the following discussion / feature in Python3.9: https://bugs.python.org/issue24416

In short, it was decided that the result of datetime.date.isocalendar would be changed to a namedtuple instead of tuple.

Now, I can see the benefit in doing that, but they also decided “to pickle” the new object (datetime.IsoCalendarDate) as a tuple:
https://github.com/python/cpython/commit/1b97b9b0ad9a2ff8eb5c8f2e2e7c2aec1d13a330#diff-2a8962dcecb109859cedd81ddc5729bea57d156e0947cb8413f99781a0860fd1R1214

So my question is, why did they make it so that creating the object directly, and “pickling-and-unpickling” the object require slightly different flows?

For example:

import datetime
from pathlib import Path
import pickle



RESULTS_CACHE_PICKLE = Path('cache.pickle')


if RESULTS_CACHE_PICKLE.is_file():
    with open(RESULTS_CACHE_PICKLE, 'rb') as f:
        icd = pickle.load(f)
else:
    icd = datetime.date(2019, 1, 1).isocalendar()
    with open(RESULTS_CACHE_PICKLE, 'wb') as f:
        pickle.dump(icd, f)
        
        
print(icd.year)

Results in:

$ python icd_test.py
2019
$ python icd_test.py
Traceback (most recent call last):
  File "icd_test.py", line 19, in <module>
    print(icd.year)
AttributeError: 'tuple' object has no attribute 'year'

This inconsistency looks unstable to me. Does it happen in other places in the language?

Advertisement

Answer

I guess, as suggested by Batman comment in this answer:

One is that namedtuple isn’t a class, it’s a class factory that returns a class, which you in turn use to make instances. (…)

And unfortunately, this is exactly the case (intentionally!) as we can read in the code of IsoCalendarDate(tuple) class:

def __reduce__(self):
    # This code is intended to pickle the object without making the
    # class public. See https://bugs.python.org/msg352381
    return (tuple, (tuple(self),))

So it seems that, for some reason, the inconsequential approach was taken intentionally but I am not aware of (m)any similar situations in Python code.

I think you can raise it as a bug. Maybe the rationale to keep IsoCalendarDate private from the pickle perspective should get revisited.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement