[issue42259] pprint: infinite recursion for saferepr() when using nested objects, but str() works

Andrei Kulakov report at bugs.python.org
Sat Dec 25 17:49:13 EST 2021


Andrei Kulakov <andrei.avk at gmail.com> added the comment:

The recursion protection in `saferepr` applies when two conditions are met: 

- the structure is subclassed from list, tuple or dict
- __repr__ is not overriden

In this case neither condition is met.

However, the recursion is caused by the `__repr__` so when it's removed, recursion doesn't happen (but not due to recursion protection).

Btw also note that recursive path must be continuous for recursion detection to apply, e.g. if it's list[cust_obj[list[cust_obj...]]], detection also won't work.

I don't think we can fix this in code in a straightforward way, because  we want to avoid recursively calling saferepr in case __repr__ does not recurse.

In other words, if we knew __repr__ DOES recurse, we could call saferepr recursively and apply recursion detection without any problems, but __repr__ might intentionally say something like "<Mylist: 1423434 items>", and then recursively calling saferepr would be undesirable.

So unfortunately we lose the recursion detection because of that.

One possible option would be to add an optional param like *force_recursion*, to recurse with detection even on overridden *__repr__*. I'm not sure it's worth it. But that's something users can consider: subclass PrettyPrinter and override saferepr() and either remove the checks for __repr__ override or add a param to do just that.

Current docs really make it sound like any recursion that shows up in repr() will be protected; it's really much more limited than that. Adding PR to clarify the limitations.

----------
versions: +Python 3.11 -Python 3.8

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue42259>
_______________________________________


More information about the Python-bugs-list mailing list