Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add_slots tool breaks pickling of frozen dataclasses & proposed solution #154

Open
ariebovenberg opened this issue Jan 11, 2020 · 0 comments

Comments

@ariebovenberg
Copy link

ariebovenberg commented Jan 11, 2020

Although not part of the official API, I find add_slots to be quite useful. However, the combination with frozen dataclasses and pickling causes problems:

@add_slots
@dataclass(frozen=True)
class ExampleDataclass:
    foo: str
    bar: int



assert ExampleDataclass.__slots__ == ("foo", "bar")

assert pickle.loads(
    pickle.dumps(ExampleDataclass("a", 1))
) == ExampleDataclass("a", 1)

gives the following error:

dataclasses.FrozenInstanceError: cannot assign to field 'foo'

A quick fix would be to add something like this:

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):
    ...  # existing add_slots code here...
    # optionally only do these steps if the dataclass is frozen
    cls.__getstate__ = _dataclass_getstate
    cls.__setstate__ = _dataclass_setstate
    return cls

edit: typos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant