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

pickle protocol 2 failure on int subclass #44151

Closed
andersjm mannequin opened this issue Oct 20, 2006 · 6 comments
Closed

pickle protocol 2 failure on int subclass #44151

andersjm mannequin opened this issue Oct 20, 2006 · 6 comments
Assignees
Labels
docs Documentation in the Doc dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@andersjm
Copy link
Mannequin

andersjm mannequin commented Oct 20, 2006

BPO 1581183
Nosy @rhettinger, @abalkin, @devdanzin, @avassalotti
Superseder
  • bpo-1062277: Pickle breakage with reduction of recursive structures
  • Files
  • int_subclass_pickle_problem.py
  • issue1581183-test-py3k.py
  • issue1581183-test.diff
  • 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:

    assignee = 'https://github.com/abalkin'
    closed_at = <Date 2010-08-16.20:00:40.663>
    created_at = <Date 2006-10-20.10:15:05.000>
    labels = ['type-bug', 'library', 'docs']
    title = 'pickle protocol 2 failure on int subclass'
    updated_at = <Date 2010-08-16.20:00:40.662>
    user = 'https://bugs.python.org/andersjm'

    bugs.python.org fields:

    activity = <Date 2010-08-16.20:00:40.662>
    actor = 'belopolsky'
    assignee = 'belopolsky'
    closed = True
    closed_date = <Date 2010-08-16.20:00:40.663>
    closer = 'belopolsky'
    components = ['Documentation', 'Library (Lib)']
    creation = <Date 2006-10-20.10:15:05.000>
    creator = 'andersjm'
    dependencies = []
    files = ['2189', '17798', '17801']
    hgrepos = []
    issue_num = 1581183
    keywords = []
    message_count = 6.0
    messages = ['30326', '84523', '108889', '108912', '108919', '110390']
    nosy_count = 5.0
    nosy_names = ['rhettinger', 'belopolsky', 'andersjm', 'ajaksu2', 'alexandre.vassalotti']
    pr_nums = []
    priority = 'low'
    resolution = 'duplicate'
    stage = 'needs patch'
    status = 'closed'
    superseder = '1062277'
    type = 'behavior'
    url = 'https://bugs.python.org/issue1581183'
    versions = ['Python 2.6', 'Python 3.2']

    @andersjm
    Copy link
    Mannequin Author

    andersjm mannequin commented Oct 20, 2006

    I ran into problems pickling a set containing an int
    subclass which holds a reference to an object which
    holds a reference to the original object.

    I reduced it to the attached
    int_subclass_pickle_problem.py. There are no problems
    with pickle protocols 0 and 1, but the protocol 2 unit
    tests fail with an exception.

    This happens for pickle and cPickle both, although with
    two different excpeptions.

    cPickle:
    TypeError: ('set objects are unhashable', <type 'set'>,
    ([set([1])],))

    pickle:
    File "....\lib\pickle.py", line 244, in memoize
    assert id(obj) not in self.memo
    AssertionError

    (For the full tracebacks, run the attached script.)

    I looked into if this was because int implemented
    __reduce__ or __reduce_ex__, trumping my
    __getstate__/setstate, but that doesn't seem to be
    the case:

    >>> int.__reduce_ex__ is object.__reduce_ex__
    True
    >>> int.__reduce__ is object.__reduce__
    True

    After the further simplification of replacing
    self.orig = [set([E.a]), set([E.a])]
    with
    self.orig = E.a
    cPickle starts working, but pickle still fails.

    (Seen with Python 2.4.3 and Python 2.5, on W2K.)

    @andersjm andersjm mannequin added stdlib Python modules in the Lib dir labels Oct 20, 2006
    @devdanzin
    Copy link
    Mannequin

    devdanzin mannequin commented Mar 30, 2009

    Confirmed on trunk, has tests.

    @devdanzin devdanzin mannequin changed the title pickle protocol 2 failure on int subclass pickle protocol 2 failure on int subclass Mar 30, 2009
    @devdanzin devdanzin mannequin added the type-bug An unexpected behavior, bug, or error label Mar 30, 2009
    @devdanzin devdanzin mannequin changed the title pickle protocol 2 failure on int subclass pickle protocol 2 failure on int subclass Mar 30, 2009
    @devdanzin devdanzin mannequin added the type-bug An unexpected behavior, bug, or error label Mar 30, 2009
    @abalkin
    Copy link
    Member

    abalkin commented Jun 29, 2010

    I reproduced the problem in py3k (both protocol 2 and 3). See bpo-1581183-test-py3k.py attached.

    @abalkin
    Copy link
    Member

    abalkin commented Jun 29, 2010

    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.

    @abalkin
    Copy link
    Member

    abalkin commented Jun 29, 2010

    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.

    @abalkin abalkin added docs Documentation in the Doc dir labels Jul 13, 2010
    @abalkin
    Copy link
    Member

    abalkin commented Jul 15, 2010

    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.

    @abalkin abalkin closed this as completed Aug 16, 2010
    @abalkin abalkin closed this as completed Aug 16, 2010
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    docs Documentation in the Doc dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant