Message261903
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
10
But 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: x
Since 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 (issue22995) in this case, since __getstate__ is looked up as instance attribute, not as other special methods. |
|
Date |
User |
Action |
Args |
2016-03-17 08:43:08 | serhiy.storchaka | set | recipients:
+ serhiy.storchaka, rhettinger, pitrou, alexandre.vassalotti |
2016-03-17 08:43:06 | serhiy.storchaka | set | messageid: <1458204186.54.0.651323931278.issue26579@psf.upfronthosting.co.za> |
2016-03-17 08:43:06 | serhiy.storchaka | link | issue26579 messages |
2016-03-17 08:43:06 | serhiy.storchaka | create | |
|