attrs icon indicating copy to clipboard operation
attrs copied to clipboard

cached properties should be pickled

Open Redoubts opened this issue 8 months ago • 1 comments

Consider the following

 @attrs.define
 class A:
     @functools.cached_property
     def x(self) -> list[int]:
         print('caching')
         return list(range(5))

The following behavior is expected:

In []: attrs.__version__
Out[]: '25.3.0'

In []: a = A()

In []: a.x
caching
Out[]: [0, 1, 2, 3, 4]

In []: a.x
Out[]: [0, 1, 2, 3, 4]

a.x is cached. However, if I round trip through pickle:

In []: pickle.loads(pickle.dumps(a)).x
caching
Out[]: [0, 1, 2, 3, 4]

the cached property is rebuilt. Usually when I used cached properties, it's to hold expensive data, and it would be nice to capture this in a pickle. Can this be supported?

Redoubts avatar Mar 21 '25 17:03 Redoubts

This seems dangerous and would have to be pre-property opt-in and I’m not sure how to do that. Just imagine the cached property determines something that is specific to the current process or machine.

If you want pickled expensive fields, I would recommend a classmethod constructor.

hynek avatar Mar 24 '25 02:03 hynek