◐ Shell
clean mode source ↗

bpo-43999: If using a frozen class with slots, add __getstate__ and __setstate__ by ericvsmith · Pull Request #25786 · python/cpython

Expand Up @@ -1087,14 +1087,28 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, tuple(f.name for f in std_init_fields))
if slots: cls = _add_slots(cls) cls = _add_slots(cls, frozen)
abc.update_abstractmethods(cls)
return cls

def _add_slots(cls): # _dataclass_getstate and _dataclass_setstate are needed for pickling frozen # classes with slots. These could be slighly more performant if we generated # the code instead of iterating over fields. But that can be a project for # another day, if performance becomes an issue. def _dataclass_getstate(self): return [getattr(self, f.name) for f in fields(self)]

def _dataclass_setstate(self, state): for field, value in zip(fields(self), state): # use setattr because dataclass may be frozen object.__setattr__(self, field.name, value)

def _add_slots(cls, is_frozen): # Need to create a new class, since we can't set __slots__ # after a class has been created.
Expand All @@ -1120,6 +1134,11 @@ def _add_slots(cls): if qualname is not None: cls.__qualname__ = qualname
if is_frozen: # Need this for pickling frozen classes with slots. cls.__getstate__ = _dataclass_getstate cls.__setstate__ = _dataclass_setstate
return cls

Expand Down