New submission from David Hagen <[email protected]>:
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 <[email protected]>
<https://bugs.python.org/issue36424>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com