avoiding recursion in repr?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David C. Fox

    avoiding recursion in repr?

    The __repr__ methods of the built-in list and dict objects properly
    avoid an infinite loop when you take the representation of a list or
    dictionary which contains itself (or more complicated nestings: list l1
    contains list l2 which contains l1, etc.).

    Looking at the CPython source code, it seems that the Py_ReprEnter and
    Py_ReprLeave functions are used to implement this protection.

    Is there any equivalent function for defining new container classes
    written in Python, or do potentially recursive containers have to be
    implemented in C?

    (I could of course try to translate these functions into Python, but I'm
    not sure that would catch mixed nestings of my class and list/dict).

    David

  • David C. Fox

    #2
    Re: avoiding recursion in repr?

    John J. Lee wrote:
    [color=blue]
    > "David C. Fox" <davidcfox@post .harvard.edu> writes:
    >
    >[color=green]
    >>The __repr__ methods of the built-in list and dict objects properly
    >>avoid an infinite loop when you take the representation of a list or
    >>dictionary which contains itself (or more complicated nestings: list
    >>l1 contains list l2 which contains l1, etc.).
    >>
    >>Looking at the CPython source code, it seems that the Py_ReprEnter and
    >>Py_ReprLeav e functions are used to implement this protection.
    >>
    >>Is there any equivalent function for defining new container classes
    >>written in Python, or do potentially recursive containers have to be
    >>implemented in C?
    >>
    >>(I could of course try to translate these functions into Python, but
    >>I'm not sure that would catch mixed nestings of my class and
    >>list/dict).[/color]
    >
    >
    > What's a "mixed nesting"?[/color]

    For example an instance m of MyList containing a list l containing the
    same instance m of MyList...
    [color=blue]
    >
    > Couldn't you just use a dict to remember objects that have been seen,
    > like copy.deep_copy?[/color]

    No. deep_copy uses a memo argument (with a default value of None) to
    pass that dictionary around, but __repr__ for standard containers.
    Therefore, in the MyList example above, m.__repr__ can't pass such a
    dictionary when it calls the l.__repr__(), so when l.__repr__ calls
    m.__repr__ it doesn't get the extra argument. If I'm understanding the
    code for lists and dictionaries correctly, I think you need something
    global and thread safe (which is what Py_ReprEnter/Leave seem to be for).

    David

    Comment

    Working...