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).
| __dict__=clsdict.pop('__dict__', None) |
| ifisinstance(__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 do setattr(cls, key, value). However, here, key is __dict__, so python thinks we actually want to override the __dict__ attribute of cls, and not a __dict__ field of the __dict__. - However, including
__dict__ in the type_kwargs only if it is a property object is kind of arbitrary (probably related to namedtuples). Take this example for example, where we loose the __dict__ attribute:
In [1]: importgc ...: importcloudpickle ...: ...: classA: ...: __dict__= {'some_attribute':1} ...: a=A() ...: print(f'calling __dict__ on the original A instance: {a.__dict__}') ...: ...: s=cloudpickle.dumps(a) ...: delA ...: dela ...: gc.collect() ...: depickled_a=cloudpickle.loads(s) ...: print(f'calling __dict__ on the depickled A instance: {depickled_a.__dict__}')
calling__dict__ontheoriginalAinstance: {'some_attribute': 1}
calling__dict__onthedepickledAinstance: {}
After #253 (comment), I started examinating these lines. I think the original use-case was to handle classes like
namedtupleoverloading__dict__.(even though the test suite passes for all python versions if simply drop the
__dict__item out ofclsdict).cloudpickle/cloudpickle/cloudpickle.py
Lines 633 to 635 in 167e163
In more detail:
__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__.__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: