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
pickle protocol 2 failure on int subclass #44151
Comments
I ran into problems pickling a set containing an int I reduced it to the attached This happens for pickle and cPickle both, although with cPickle: pickle: (For the full tracebacks, run the attached script.) I looked into if this was because int implemented >>> int.__reduce_ex__ is object.__reduce_ex__
True
>>> int.__reduce__ is object.__reduce__
True After the further simplification of replacing (Seen with Python 2.4.3 and Python 2.5, on W2K.) |
Confirmed on trunk, has tests. |
I reproduced the problem in py3k (both protocol 2 and 3). See bpo-1581183-test-py3k.py attached. |
At least part of the problem has nothing to do with subclassing from int and instead is related to pickling objects with circular references. I am attaching a patch that demonstrates the problem. In bpo-1581183-test.diff, I modified memoize so that it does nothing rather than fails an assert if object is already in the memo. This makes python and C implementations behave the same, but still fail to produce correct results. Pickling with protocol 2 break circular reference and instead creates two independent objects. |
Upon further investigation, I conclude that the problem is in the user code. I am attaching int_subclass_pickle_problem_fixed.py which fixes the user code as follows: def __getnewargs__(self):
- return (int(self), self.an_enum)
+ return (int(self), None) Note that with this change, the object is pickled correctly because __setstate__ takes care of resetting self.an_enum. The problem is that self-referential state should not be passed via __getnewargs__ mechanism. This is because when pickler starts writing newargs, it is already committed to creating a new object (otherwise it would not need to serialize newargs in the first place.) If the newargs contain the object that is being pickled, it will be serialized twice unless this situation is caught in memoize. What can be improved, is the diagnostic and possibly documentation. If after saving newargs, memo contains the object that is being pickled, an exception should be raised explaining that __getnewargs__() should not contain self-references. |
I am going to close this as a duplicate of bpo-1062277. The later has a patch, but Raymond questioned whether proposed feature is desirable. [msg47268] I am -1, but will look at the patch there. |
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: