[Python-ideas] Shrink recursion error tracebacks (was: Have REPL print less by default)

Émanuel Barry vgr255 at live.ca
Wed Apr 20 00:07:11 EDT 2016


This idea was mentioned a couple of times in the previous thread, and it
seems reasonable to me. Getting recursion errors when testing a function in
the interactive prompt often screwed me over, as I have a limited scrollback
of 1000 lines at best on Windows (I never checked exactly how high/low the
limit was), and with Python's recursion limit of 1000, that's a whopping
1000 to 2000 lines in my console, effectively killing off anything useful I
might have wanted to see. Such as, for example, the function definition that
triggered the exception.

Of course, the same is true for actual programs, where tracebacks drown off
everything else useful. For all we know, a typo caused a NameError in one of
the functions which somehow triggered it to call itself over again until
Python decided it was enough, but you can't know that because your entire
scrollback is full of

File "<stdin>", line 1, in func

And, for programs that are user-facing, I take all tracebacks and redirect
them to a file that the user can submit me so I can debug the issue, and
having tens of hundreds of the same line hurts readability.

The issue that the output from running a certain script in the REPL and as a
script would differ has been raised, and I am of the opinion that in no way,
shape or form should the two have different behaviours (the exception being
sys.ps1, sys.ps2 and builtins._ in interactive mode, which are 100% fine).
I'm suggesting a change to how Python handles specifically recursion limits,
to cut after a sane number of times (someone suggested to shrink the output
after 3 times), and simply stating how many more identical messages there
are. I would also like to extend this to any arbitrary loop of callers (for
example foo -> bar -> baz -> foo and so on would be counted as one "call"
for the purposes of this proposal).

Under this proposal, something similar to this would happen:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in func
  File "<stdin>", line 1, in func
  File "<stdin>", line 1, in func
    [Previous 1 message(s) repeated 996 more times]
RecursionError: maximum recursion depth exceeded

With multiple chained calls (I don't know how hard it would be to implement
this, probably not trivial):

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in foo
  File "<stdin>", line 1, in bar
  File "<stdin>", line 1, in baz
  File "<stdin>", line 1, in foo
  File "<stdin>", line 1, in bar
  File "<stdin>", line 1, in baz
  File "<stdin>", line 1, in foo
  File "<stdin>", line 1, in bar
  File "<stdin>", line 1, in baz
    [Previous 3 message(s) repeated 330 more times]
RecursionError: maximum recursion depth exceeded

We can probably afford to cut out immediately as we notice the recursion,
but even just 3 times with multiple chained calls isn't going to be anywhere
near as long as it currently is.

Thoughts? Suggestions? Something I forgot?

-Emanuel


More information about the Python-ideas mailing list