Skip to content

dill fails to pickle attrs-created classes #411

@pganssle

Description

@pganssle

It seems that dill is doing something that breaks pickling of attrs-created classes. Here is an MWE that shows that dill.dumps fails where pickle.dumps would succeed:

import attr
import dill
import pickle


@attr.s
class A:
    a = attr.ib()


if __name__ == "__main__":
    v = A(1)
    print(f"Pickling {v}")
    print(pickle.dumps(v))

    print(f"Dill pickling {v}")
    print(dill.dumps(v))

Here is the result, with traceback:

Details
Pickling A(a=1)
b'\x80\x04\x95\x1f\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x01A\x94\x93\x94)\x81\x94}\x94\x8c\x01a\x94K\x01sb.'
Dill pickling A(a=1)
Traceback (most recent call last):
  File "/tmp/tmp.sQU1rFY7Ax/mwe.py", line 17, in <module>
    print(dill.dumps(v))
  File "/tmp/tmp.sQU1rFY7Ax/venv/lib/python3.9/site-packages/dill/_dill.py", line 273, in dumps
    dump(obj, file, protocol, byref, fmode, recurse, **kwds)#, strictio)
  File "/tmp/tmp.sQU1rFY7Ax/venv/lib/python3.9/site-packages/dill/_dill.py", line 267, in dump
    Pickler(file, protocol, **_kwds).dump(obj)
  File "/tmp/tmp.sQU1rFY7Ax/venv/lib/python3.9/site-packages/dill/_dill.py", line 454, in dump
    StockPickler.dump(self, obj)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 487, in dump
    self.save(obj)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 603, in save
    self.save_reduce(obj=obj, *rv)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 687, in save_reduce
    save(cls)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 560, in save
    f(self, obj)  # Call unbound method with explicit self
  File "/tmp/tmp.sQU1rFY7Ax/venv/lib/python3.9/site-packages/dill/_dill.py", line 1373, in save_type
    pickler.save_reduce(_create_type, (type(obj), obj.__name__,
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 692, in save_reduce
    save(args)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 560, in save
    f(self, obj)  # Call unbound method with explicit self
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 901, in save_tuple
    save(element)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 560, in save
    f(self, obj)  # Call unbound method with explicit self
  File "/tmp/tmp.sQU1rFY7Ax/venv/lib/python3.9/site-packages/dill/_dill.py", line 941, in save_module_dict
    StockPickler.save_dict(pickler, obj)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 971, in save_dict
    self._batch_setitems(obj.items())
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 997, in _batch_setitems
    save(v)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 603, in save
    self.save_reduce(obj=obj, *rv)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 687, in save_reduce
    save(cls)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 560, in save
    f(self, obj)  # Call unbound method with explicit self
  File "/tmp/tmp.sQU1rFY7Ax/venv/lib/python3.9/site-packages/dill/_dill.py", line 1390, in save_type
    StockPickler.save_global(pickler, obj, name=name)
  File "/home/nlx5/.pyenv/versions/3.9.4/lib/python3.9/pickle.py", line 1070, in save_global
    raise PicklingError(
_pickle.PicklingError: Can't pickle <class 'AAttributes'>: it's not found as builtins.AAttributes

I believe the issue has something to do with the way dill is trying to save the attrs-created class. It runs up against this ad-hoc class created with eval and breaks. I am not sure why pickle doesn't have this problem.

I have tested this with several attrs versions between 18.2.0 and 21.2.0, as well as with dill versions going back to 0.2.5, and all versions are affected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions