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
>>list/dict).
> 
> 
> 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).

David





More information about the Python-list mailing list