This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author drhagen
Recipients drhagen
Date 2019-03-25.15:18:08
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1553527088.82.0.636469633332.issue36424@roundup.psfhosted.org>
In-reply-to
Content
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
History
Date User Action Args
2019-03-25 15:18:08drhagensetrecipients: + drhagen
2019-03-25 15:18:08drhagensetmessageid: <1553527088.82.0.636469633332.issue36424@roundup.psfhosted.org>
2019-03-25 15:18:08drhagenlinkissue36424 messages
2019-03-25 15:18:08drhagencreate