Skip to content

Classes and instances produced by dataclasses.make_dataclass are not pickleable #102103

Closed
@sobolevn

Description

@sobolevn

Repro:

## Setup

>>> import pickle
>>> import dataclasses
>>> A = dataclasses.make_dataclass('A', [])
>>> @dataclasses.dataclass
... class B: pass
... 

## Correct

>>> pickle.loads(pickle.dumps(B))
<class '__main__.B'>
>>> pickle.loads(pickle.dumps(B()))
B()

## Wrong

>>> pickle.load(pickle.dump(A))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'types.A'>: attribute lookup A on types failed

>>> pickle.loads(pickle.dumps(A()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'types.A'>: attribute lookup A on types failed

I think that this happens because of this:

>>> A.__module__
'types'
>>> B.__module__
'__main__'

After a manual fix it works as it should:

>>> A.__module__ = '__main__'
>>> pickle.loads(pickle.dumps(A()))
A()

So, I propose to do it for all dataclasses that we create in make_dataclass.

I have a simple PR ready, it is inspired by namedtuple's logic :)

Linked PRs

Metadata

Metadata

Assignees

Labels

stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions