Reputation: 16335
While using pickle.load(...)
, there's a possibility that AttributeError: can't set attribute
is raised. However on a bigger pickle file this error doesn't help at all (because I have no idea what causes it).
Are there any ways to get more information or to debug this? If there are any other advices how to deal with this problem, I would be glad to hear them!
The error originally comes from Jedi's parser branch. The issue is caused by the latest changes in jedi.parser.fast
. If you want to see the error, you need to run python test/run.py on_import 100
twice.
>>> X.y = 3
>>> class X():
... @property
... def y(self): pass
...
>>> X().y = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
The cause is this AttributeError that gives you no information. Combine that with an inheritance of __slots__
and properties in the inherited object + pickle and you get this unclear error.
I still think that it's pickle's fault. I'm going to leave this question open, because I still haven't found a way to debug it properly. Pickle should take that AttributeError
and modify it.
Upvotes: 2
Views: 1778
Reputation: 35247
dill
has pickle debugging tools in dill.detect
. I can't see what object you'd like to debug as your code above is not due to pickle
… but I can show an example below, regardless.
>>> class Test(object):
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> x = (i for i in range(10))
>>> y = iter(range(10))
>>>
>>> t = Test(x,y)
>>>
>>> import dill
>>> dill.detect.errors(t)
PicklingError("Can't pickle <type 'listiterator'>: it's not found as __builtin__.listiterator",)
>>> dill.detect.badobjects(t)
<__main__.Test object at 0x1086970d0>
>>> dill.detect.badobjects(t, 1)
{'__hash__': <method-wrapper '__hash__' of Test object at 0x1086970d0>, '__setattr__': <method-wrapper '__setattr__' of Test object at 0x1086970d0>, '__reduce_ex__': <built-in method __reduce_ex__ of Test object at 0x1086970d0>, 'y': <listiterator object at 0x108890d50>, '__reduce__': <built-in method __reduce__ of Test object at 0x1086970d0>, '__str__': <method-wrapper '__str__' of Test object at 0x1086970d0>, '__format__': <built-in method __format__ of Test object at 0x1086970d0>, '__getattribute__': <method-wrapper '__getattribute__' of Test object at 0x1086970d0>, '__delattr__': <method-wrapper '__delattr__' of Test object at 0x1086970d0>, '__repr__': <method-wrapper '__repr__' of Test object at 0x1086970d0>, '__dict__': {'y': <listiterator object at 0x108890d50>, 'x': <generator object <genexpr> at 0x108671f50>}, 'x': <generator object <genexpr> at 0x108671f50>, '__sizeof__': <built-in method __sizeof__ of Test object at 0x1086970d0>, '__init__': <bound method Test.__init__ of <__main__.Test object at 0x1086970d0>>}
>>> dill.detect.trace(True)
>>> dill.dumps(t)
T2: <class '__main__.Test'>
F2: <function _create_type at 0x10945c410>
T1: <type 'type'>
F2: <function _load_type at 0x10945c398>
T1: <type 'object'>
D2: <dict object at 0x10948b7f8>
F1: <function __init__ at 0x108894938>
F2: <function _create_function at 0x10945c488>
Co: <code object __init__ at 0x108873830, file "<stdin>", line 2>
F2: <function _unmarshal at 0x10945c320>
D1: <dict object at 0x1085b9168>
D2: <dict object at 0x10947e910>
D2: <dict object at 0x108898910>
T4: <type 'listiterator'>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
#...snip...
pickle.PicklingError: Can't pickle <type 'listiterator'>: it's not found as __builtin__.listiterator
>>>
I couldn't think of a case where there's an AssertionError
from a pickle.dump
off the top of my head... but the above debugging tools should work exactly the same way in that case.
If you post a simple reproducible object (i.e. standard lib preferably) that produces an AttributeError on pickling, I'll update my example.
Upvotes: 1