Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upincorrect results for copy.copy() of various Stackless picklable types #127
Comments
|
Original comment by Anselm Kruis (Bitbucket: akruis, GitHub: akruis): I just discovered, that C-Python 3.3 can pickle the types iterator and callable_iterator. Why didn't Kristján comment them in 0bbd8721729f? I'm going to remove the pickling code, but I'll keep the unpickling code in 3.3-slp and 3.4-slp to stay compatible. |
…ests. This change is based on f5f98595c6cc63b from 2.7-slp, but it is heavily modified for Python 3. - Pickle 'callable-iterator' objects correctly. Previously the unpickled object had the type '_stackless._wrap.callable-iterator'. - Fix pickling of 'method-wrapper' objects. Previously pickling them caused a SystemError exception. - Fix copy.copy() for 'callable-iterator', 'method', 'dict_keys', 'dict_values' and 'dict_items' objects. Previously the copied object had the type '_stackless._wrap....'. - Fix Stackless pickling tests. The method StacklessTestCase.dumps() didn't pass the pickle protocol to the pickler. - Remove dead code in prickelpit.c. The code was used in older Stackless versions.
…d traceback objects __setstate__ must accept the state returned by __reduce__. This was not the case for generator and trace-back objects. This commit fixes this. The next commit (merge of issue #127) adds the relevant test cases. Additionally amends changelog.txt. https://bitbucket.org/stackless-dev/stackless/issues/107
Disable the Stackless specific code for pickling 'iterator' and 'callable_iterator' objects. C-Python 3.3 already pickles them. Add tests to ensure, that Stackless can still unpickle old pickles. https://bitbucket.org/stackless-dev/stackless/issues/127
Originally reported by: Anselm Kruis (Bitbucket: akruis, GitHub: akruis)
Affected versions: all
Problem
Stackless can pickle a few more types than C-Python. A pickleable object can also be copied by copy.copy(). Therefore copy.copy() should work for all Stackless-pickleable types. Unfortunately if you copy a callable-iterator, you get a copy of type '_stackless._wrap.callable-iterator'
For Stackless 2.7.13 this problem is caused by a bug in prickelpit.c calliter_reduce(). The reduce function returns only a 2-tuple without a state value. Without a state, Python does not call __setstate__() on the newly created object. But Stackless changes the object type of the newly created object in __setstate__(). The fix is simple: return an empty state.
But in some versions of Python 3.x (see bpo-25718) copy.copy() contains am incorrect optimization: If copy.copy() uses a reduce-method (either from copy_reg.dispatch_table or obj.__reduce__() or obj.__reduce_ex__()), it does not call newobj.__setstate__(state), if the boolean value of state is false.
This can break Stackless, because it depends on __setstate__() being called.
Additionally I found, that bug in the pickle tests of Stackless Python 3.x. The pickles protocol value isn't passed the the pickler. Therefore it always uses the default protocol.
Solution