Skip to content

cloudpickle drops __dict__ attribute of classes. #282

Description

@pierreglaser

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: {}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions