avoiding recursion in repr?
David C. Fox
davidcfox at post.harvard.edu
Thu Dec 4 07:55:16 CET 2003
John J. Lee wrote:
> "David C. Fox" <davidcfox at post.harvard.edu> writes:
>>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
> What's a "mixed nesting"?
For example an instance m of MyList containing a list l containing the
same instance m of MyList...
> Couldn't you just use a dict to remember objects that have been seen,
> like copy.deep_copy?
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).
More information about the Python-list