Search code examples
pythonpickleslotspython-dataclasses

Pickle a frozen dataclass that has __slots__


How do I pickle an instance of a frozen dataclass with __slots__? For example, the following code raises an exception in Python 3.7.0:

import pickle
from dataclasses import dataclass

@dataclass(frozen=True)
class A:
  __slots__ = ('a',)
  a: int

b = pickle.dumps(A(5))
pickle.loads(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'a'

This works if I remove either the frozen or the __slots__. Is this just a bug?


Solution

  • Starting in Python 3.10.0, this works but only if you specify the slots via slots=True in the dataclass decorator. It does not work, and probably will never work, with __slots__ manually specified.

    import pickle
    from dataclasses import dataclass
    
    @dataclass(frozen=True, slots=True)
    class A:
      a: int
    
    b = pickle.dumps(A(5))
    pickle.loads(b)  # A(a=5)