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

eliminate recursion in pickling #46732

Closed
cyhawk mannequin opened this issue Mar 25, 2008 · 9 comments
Closed

eliminate recursion in pickling #46732

cyhawk mannequin opened this issue Mar 25, 2008 · 9 comments
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@cyhawk
Copy link
Mannequin

cyhawk mannequin commented Mar 25, 2008

BPO 2480
Nosy @jcea, @bkline, @avassalotti
Superseder
  • bpo-3119: pickle.py is limited by python's call stack
  • Files
  • bugdemo.py: bug demo
  • nonrecursivepickler.py: Alternative implementation of Pickler, that does not have this limitation
  • picklertest.py: A small test I used to verify my modification
  • nonrecursivepickler-fixed.py
  • 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 = None
    closed_at = <Date 2009-06-29.00:19:33.677>
    created_at = <Date 2008-03-25.13:44:45.378>
    labels = ['type-feature', 'library']
    title = 'eliminate recursion in pickling'
    updated_at = <Date 2009-06-29.00:19:33.675>
    user = 'https://bugs.python.org/cyhawk'

    bugs.python.org fields:

    activity = <Date 2009-06-29.00:19:33.675>
    actor = 'alexandre.vassalotti'
    assignee = 'none'
    closed = True
    closed_date = <Date 2009-06-29.00:19:33.677>
    closer = 'alexandre.vassalotti'
    components = ['Library (Lib)']
    creation = <Date 2008-03-25.13:44:45.378>
    creator = 'cyhawk'
    dependencies = []
    files = ['9847', '9850', '9851', '9852']
    hgrepos = []
    issue_num = 2480
    keywords = []
    message_count = 9.0
    messages = ['64481', '64492', '64493', '65799', '65870', '65877', '65927', '68965', '89802']
    nosy_count = 6.0
    nosy_names = ['jcea', 'bkline', 'alexandre.vassalotti', 'schmir', 'cyhawk', 'habnabit']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = None
    status = 'closed'
    superseder = '3119'
    type = 'enhancement'
    url = 'https://bugs.python.org/issue2480'
    versions = ['Python 2.5']

    @cyhawk
    Copy link
    Mannequin Author

    cyhawk mannequin commented Mar 25, 2008

    In the attached demo I create a graph of 250 nodes, all of which are
    connected to every other node, and this is represented by a set
    attribute of the Node objects.

    When I try to pickle this graph, it fails in various ways. In regular
    pickle it is always a "maximum recursion depth exceeded" error. In
    cPickle it is either a KeyError or a silent termination of the process.
    (As tested on Windows XP 32 bits.) It depends on the size of the graph.
    For smaller graphs (say 100 nodes) it works fine.

    If connections are described using a dictionary or even a list, I get
    the same errors.

    @cyhawk cyhawk mannequin added the stdlib Python modules in the Lib dir label Mar 25, 2008
    @cyhawk
    Copy link
    Mannequin Author

    cyhawk mannequin commented Mar 25, 2008

    So now I've learned that this is a result of the way Pickler is
    implemented. I think that it would make sense to create an
    implementation that is not that recursive and that would handle such
    structures better.

    I have now written one such implementation that is a subclass of the
    original pickler and handles recursive data structures. I presume that
    it is inferior in a couple of ways (performance and memory efficiency
    probably), but a complete rewrite could probably create an
    implementation that handles recursive data structures and is not inferior.

    @cyhawk cyhawk mannequin changed the title pickling of recursive sets of objects fails pickling of large recursive structures fails Mar 25, 2008
    @cyhawk
    Copy link
    Mannequin Author

    cyhawk mannequin commented Mar 25, 2008

    Sidenote: If I click "edit" for nonrecursivepickler.py, I get told that
    "File has been classified as spam." Strange. Should I not use Viagra as
    a classname? :) (j/k I didn't do anything like that)

    However I have now fixed a mistake in my code.

    @bkline
    Copy link
    Mannequin

    bkline mannequin commented Apr 25, 2008

    I just ran into this behavior with an attempt to pickle a dom tree for
    an XML document whose nesting level never got deeper than nine child
    nodes, and indeed it crashed the interpreter. Throwing an exception
    would be preferable, of course, to silent blowing up Python, but even
    the exception seems to fly in the face of the documentation for the
    pickle module [1] which claims (summarizing) that serializing recursive
    objects using marshal will fail but pickling recursive objects will not
    fail. I can provide a repro for the XML/DOM pickling case if you think
    that would be helpful, but that seems redundant since essentially you've
    already illustrated the problem with your own repro case. Thanks for
    your work on the solution.

    [1] http://docs.python.org/lib/node314.html

    @bkline bkline mannequin added the type-crash A hard crash of the interpreter, possibly with a core dump label Apr 25, 2008
    @avassalotti
    Copy link
    Member

    Bob Kline wrote:

    I just ran into this behavior with an attempt to pickle a dom tree
    for an XML document whose nesting level never got deeper than nine
    child nodes, and indeed it crashed the interpreter.

    Pickling recursive data-structure should not crash the interpreter.
    Please open a new issue and don't forget to provide an example case.

    the documentation for the pickle module 1 which claims (summarizing)
    that serializing recursive objects using marshal will fail but
    pickling recursive objects will not fail.

    The section of documentation, you are referring to, uses the term
    "recursive object" to means an object which contains a reference to
    itself. Anyway, the documentation 1 states clearly:

    Trying to pickle a highly recursive data structure may exceed the
    maximum recursion depth, a RuntimeError will be raised in this
    case. You can carefully raise this limit with sys.setrecursionlimit().

    @avassalotti avassalotti added type-feature A feature request or enhancement and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Apr 27, 2008
    @cyhawk
    Copy link
    Mannequin Author

    cyhawk mannequin commented Apr 27, 2008

    I have also described the crash, but it makes sense to handle it
    separately. So I have created bpo-2702, and changed the title of this
    issue.

    @cyhawk cyhawk mannequin changed the title pickling of large recursive structures fails eliminate recursion in pickling Apr 27, 2008
    @bkline
    Copy link
    Mannequin

    bkline mannequin commented Apr 28, 2008

    Please open a new issue and don't forget to provide an example case.

    Looks like Daniel beat me to the punch.

    @habnabit
    Copy link
    Mannequin

    habnabit mannequin commented Jun 29, 2008

    I've provided an alternate implementation of this that works with very
    minimal modification to pickle.py. See bpo-3119 for the patch.

    @avassalotti
    Copy link
    Member

    I am closing this issue in favour of bpo-3119, since Aaron's patch is
    cleaner and slightly faster.

    Thank you Daniel for the idea!

    @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
    stdlib Python modules in the Lib dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant