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