[New-bugs-announce] [issue36424] Pickle fails on frozen dataclass that has slots

David Hagen report at bugs.python.org
Mon Mar 25 11:18:08 EDT 2019


New submission from David Hagen <david at drhagen.com>:

If a dataclass is `frozen` and has `__slots__`, then unpickling an instance of it fails because the default behavior is to use `setattr` which `frozen` does not allow.

```
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 has a straightforward workaround, namely to use `object.setattr`.

```
import pickle
from dataclasses import dataclass

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

    def __getstate__(self):
        return dict(
            (slot, getattr(self, slot))
            for slot in self.__slots__
            if hasattr(self, slot)
        )

    def __setstate__(self, state):
        for slot, value in state.items():
            object.__setattr__(self, slot, value)


b = pickle.dumps(A(5))
pickle.loads(b)
```

It would be nice if this was fixed for all frozen, slotted dataclasses.

Originally report on SO: https://stackoverflow.com/questions/55307017/pickle-a-frozen-dataclass-that-has-slots

----------
messages: 338803
nosy: drhagen
priority: normal
severity: normal
status: open
title: Pickle fails on frozen dataclass that has slots
type: behavior
versions: Python 3.7

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue36424>
_______________________________________


More information about the New-bugs-announce mailing list