-
Notifications
You must be signed in to change notification settings - Fork 183
Open
Description
After #253 (comment), I started examinating these lines. I think the original use-case was to handle classes like namedtuple overloading __dict__.
(even though the test suite passes for all python versions if simply drop the __dict__ item out of clsdict).
cloudpickle/cloudpickle/cloudpickle.py
Lines 633 to 635 in 167e163
| __dict__ = clsdict.pop('__dict__', None) | |
| if isinstance(__dict__, property): | |
| type_kwargs['__dict__'] = __dict__ |
In more detail:
- The first one line is necessary because updating a
__dict__field in the__dict__of a class is simply not possible. Indeed,__dict__attributes are proxies objects and do not support direct item assigment like__dict__[k] = v. Instead, the canonical way to update a class__dict__is to dosetattr(cls, key, value). However, here,keyis__dict__, so python thinks we actually want to override the__dict__attribute ofcls, and not a__dict__field of the__dict__. - However, including
__dict__in thetype_kwargsonly if it is apropertyobject is kind of arbitrary (probably related to namedtuples). Take this example for example, where we loose the__dict__attribute:
In [1]: import gc
...: import cloudpickle
...:
...: class A:
...: __dict__ = {'some_attribute':1}
...: a = A()
...: print(f'calling __dict__ on the original A instance: {a.__dict__}')
...:
...: s = cloudpickle.dumps(a)
...: del A
...: del a
...: gc.collect()
...: depickled_a = cloudpickle.loads(s)
...: print(f'calling __dict__ on the depickled A instance: {depickled_a.__dict__}')
calling __dict__ on the original A instance: {'some_attribute': 1}
calling __dict__ on the depickled A instance: {}Metadata
Metadata
Assignees
Labels
No labels