classification
Title: Pickle breakage with reduction of recursive structures
Type: behavior Stage: needs patch
Components: Library (Lib) Versions: Python 3.2, Python 3.1, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder: Cannot pickle self-referencing sets
View: 9269
Assigned To: belopolsky Nosy List: ajaksu2, alex, alexandre.vassalotti, bcroq, belopolsky, ddorfman, rhettinger
Priority: normal Keywords: patch

Created on 2004-11-08 08:06 by ddorfman, last changed 2011-04-24 18:34 by alex.

Files
File name Uploaded Description Edit
redcycle.diff ddorfman, 2004-11-08 08:06 Diff
issue1062277-test-py3k.diff belopolsky, 2010-07-15 06:34 review
Messages (6)
msg47267 - (view) Author: Dima Dorfman (ddorfman) Date: 2004-11-08 08:06
Fix problems related to reduce cycles during pickling. A
"reduce cycle" is what happens when a __reduce__
implementation returns an args that cycles back through the
object it tried to reduce. This can't work because the
unpickler has to call the constructor with those args, but
it doesn't yet have that object to be able to place inside
the args. There are two problems related to this:

  1. The standard reduce implementation for proto < 2 in
     copy_reg (_reduce_ex) doesn't correctly deal with
     recursive structures. reduce_2 in typeobject.c does the
     right thing by using listitems and dictitems. Fix
     _reduce_ex by making it do the same thing. This is okay
     for proto < 2 because those arguments are a pickler-
     side feature. Tested in test_stdreducecycle.

  2. Our pickle implementations don't check for reduce
     cycles. This is somewhat cosmetic except that stack
     overflow protection is imperfect (for cPickle), causing
     crashes, and some kinds of cycles trigger asserts (in
     pickle). Fixed in pickle and cPickle by introducing a
     reducing_now set; on entering save_reduce, the object
     id being saved must not be in that set or we've been
     called recursively while saving the callable or
     arguments. Tested in test_reduce_cycle.

This shouldn't change any semantics. That reduce shouldn't
introduce cycles through args isn't documented, but it can't
work any other way.

Possible improvement: If we want to support reducing of real
immutable containers we might have to relax the reduction
cycle test to give the cycle a chance of resolving itself
normally (by constructing a partial object to pass to the
constructor and filling it in later). I'm not sure if this
trouble is worth it just to avoid writing a
frozenset.__setstate__.

See also: http://mail.python.
org/pipermail/python-dev/2004-October/049714.html

It would be very good if someone familiar with pickle
reviewed this; I am still not very confident that I
completely understand all the issues.
msg47268 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-11-09 07:31
Logged In: YES 
user_id=80475

IMO, this is more of a feature request than a bug.  Also, it
needs to be fully thought-out and discussed.  Putting this
sort of thing in just before the Py2.4 release candidate is
probably not wise.
msg47269 - (view) Author: Dima Dorfman (ddorfman) Date: 2004-11-09 09:06
Logged In: YES 
user_id=908995

Triggering assertions (pickle) and producing incorrect output
(cPickle) are certainly bugs, and being able to pickle a
recursive structure is not a feature request. The copy_reg
part of the patch is the real fix, and as it's almost a
translation of what reduce_2 already does, it should be safe
for 2.4. I agree that the rest of the patch--to check for
cycles during pickling--should wait until 2.5.
msg82105 - (view) Author: Daniel Diniz (ajaksu2) Date: 2009-02-14 18:45
Patch has test, can someone try it? I think it might be fixed already.
msg110350 - (view) Author: Alexander Belopolsky (belopolsky) (Python committer) Date: 2010-07-15 06:34
The issue is still present in py3k.  Attaching an updated patch with tests only.  Is this the same as issue998998?
msg110868 - (view) Author: Alexander Belopolsky (belopolsky) (Python committer) Date: 2010-07-20 05:38
As I explained in msg110617 under issue9269, it is possible that we can do better than simply detect reduce cycles and bail out.

I am torn between two options:

1. Reject this patch and wait until a proper solution is found.

2. Admit that better is the enemy of good and start with proper error reporting on reduce cycles by accepting this patch.

My only concern about this patch is that it is likely to affect performance because pickling will have to maintain the "reducing_now" dictionary that is parallel to the memo dictionary.
History
Date User Action Args
2011-04-24 18:34:59alexsetnosy: + alex
2011-03-08 12:59:22bcroqsetnosy: + bcroq
2010-08-19 18:26:57BreamoreBoysettype: enhancement -> behavior
versions: + Python 3.1
2010-07-20 05:38:29belopolskysetsuperseder: Cannot pickle self-referencing sets
messages: + msg110868
2010-07-20 05:11:35terry.reedysetnosy: rhettinger, belopolsky, ddorfman, ajaksu2, alexandre.vassalotti
components: + Library (Lib), - Interpreter Core
2010-07-16 00:16:58belopolskylinkissue9269 dependencies
2010-07-15 21:55:54belopolskylinkissue1581183 superseder
2010-07-15 06:34:45belopolskysetfiles: + issue1062277-test-py3k.diff

nosy: + belopolsky, alexandre.vassalotti
versions: + Python 3.2
messages: + msg110350

assignee: belopolsky
stage: needs patch
2009-02-14 18:45:34ajaksu2settype: enhancement
messages: + msg82105
nosy: + ajaksu2
versions: + Python 2.7
2004-11-08 08:06:54ddorfmancreate