New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support pickling slots in subclasses of common classes #70766
Comments
|
Pickling and copying instances of subclasses of some basic classes pickles and copies instance attributes. Example: >>> class BA(bytearray):
... pass
...
>>> b = BA(b'abc')
>>> b.x = 10
>>> c = copy.copy(b)
>>> c.x
10
>>> c = pickle.loads(pickle.dumps(b))
>>> c.x
10But this doesn't work if attributes are saved not in instance dictionary, but in slots. >>> class BA(bytearray):
... __slots__ = ('x',)
...
>>> b = BA(b'abc')
>>> b.x = 10
>>> c = copy.copy(b)
>>> c.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: x
>>> c = pickle.loads(pickle.dumps(b))
>>> c.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: xSince using __slots__ is implementation detail, this failure can be considered as a bug. Proposed patch adds support of pickling and copying slots in subclasses of all classes that already support pickling and copying non-slot attributes. It is backward compatible, classes with slots can be unpickled on older Python versions without slots. Affected classes: bytearray, set, frozenset, weakref.WeakSet, collections.OrderedDict, collections.deque, datetime.tzinfo. The patch adds the copyreg._getstate() function for Python classes and exposes the _PyObject_GetState() function for extension classes. An alternative (and simpler for end user) solution would be to add default implementation as object.__getstate__(). But this is not easy to reject non-pickleable classes (bpo-22995) in this case, since __getstate__ is looked up as instance attribute, not as other special methods. |
|
Synchronized with current sources. |
|
An alternative way is to expose a default state as object.__getstate__(). It is more efficient since it is implemented in C. Following patch implements this approach. |
This is needed after the changes in python/cpython#70766 Since object now has a __getstate__ method we need to make sure not to call it with any arguments. Probably the __getstate__ methods can be simplified (or removed?) in light of the cpython changes but for now this is a quick fix to restore previous behaviour.
This is needed after the changes in python/cpython#70766 Since object now has a __getstate__ method we need to make sure not to call it with any arguments. Probably the __getstate__ methods can be simplified (or removed?) in light of the cpython changes but for now this is a quick fix to restore previous behaviour.
This is needed after the changes in python/cpython#70766 Since object now has a __getstate__ method we need to make sure not to call it with any arguments. Probably the __getstate__ methods can be simplified (or removed?) in light of the cpython changes but for now this is a quick fix to restore previous behaviour.


serhiy-storchaka commentedMar 17, 2016
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: