Skip to content
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

incorrect results for copy.copy() of various Stackless picklable types #127

Closed
ghost opened this issue Apr 13, 2017 · 2 comments
Closed

Comments

@ghost
Copy link

ghost commented Apr 13, 2017

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

  1. I'll add a test class with a copy.copy() test case for each Stackless-picklable type.
  2. I'll fix the callable-iterator bug.
  3. In Python 3, I'll eventually add a dummy item to the state. Probably a single None value will be enough.
  4. I'll fix the protocol value issue.

@ghost
Copy link
Author

ghost commented Apr 14, 2017

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.

@ghost
Copy link
Author

ghost commented Apr 15, 2017

Original comment by Anselm Kruis (Bitbucket: akruis, GitHub: akruis):


Fixed in changeset:

  • 2.7-slp: f5f98595c6cc
  • 3.3-slp: cf4d071d72f8
  • 3.4-slp: b5da0ec04b56
  • 3.5-slp: 56a4ed32b91d

Not yet merged into default-slp.

@ghost ghost closed this as completed Sep 24, 2017
akruis pushed a commit that referenced this issue Oct 29, 2017
…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.
akruis pushed a commit that referenced this issue Oct 29, 2017
…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
akruis pushed a commit that referenced this issue Oct 29, 2017
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
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

0 participants