[Python-ideas] Have REPL print less by default
Terry Reedy
tjreedy at udel.edu
Tue Apr 19 18:28:40 EDT 2016
On 4/19/2016 12:18 PM, Steven D'Aprano wrote:
> I mostly agree with what you say, but I would like to see one change to
> the default sys.excepthook: large numbers of *identical* traceback lines
> (as you often get with recursion errors) should be collapsed. For
> example:
Tracebacks produce *pairs* of lines: the location and the line itself.
Replacing pairs with a count of repetitions would not lose information,
and would make the info more visible. I would require at least, say, 3
repetitions before collapsing.
> py> sys.setrecursionlimit(20)
> py> fact(30) # obvious recursive factorial
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", line 3, in fact
return fact(n-1)
> File "<stdin>", line 3, in fact
return fact(n-1)
> File "<stdin>", line 3, in fact
<etc>
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 3, in fact
> File "<stdin>", line 2, in fact
> RuntimeError: maximum recursion depth exceeded in comparison
>
>
> Try as I might, I just don't see the value of manually counting all
> those 'File "<stdin>", line 3, in fact' lines to find out where the
> recursive call failed :-)
>
> I think that it would be better if identical lines were collapsed,
> something like this:
>
>
> import sys
> import traceback
> from itertools import groupby
> TEMPLATE = " [...repeat previous line %d times...]\n"
>
> def collapse(seq, minimum, template=TEMPLATE):
> for key, group in groupby(seq):
> group = list(group)
> if len(group) < minimum:
> for item in group:
> yield item
> else:
> yield key
> yield template % (len(group)-1)
>
> def shortertb(*args):
> lines = traceback.format_exception(*args)
> sys.stderr.write(''.join(collapse(lines, 3)))
>
> sys.excepthook = shortertb
>
>
>
> which then gives tracebacks like this:
>
>
> py> sys.setrecursionlimit(200)
> py> a = fact(10000)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", line 3, in fact
return fact(n-1)
> [...repeat previous line 197 times...]
[repeat previous pair of lines 197 times]
> File "<stdin>", line 2, in fact
> RuntimeError: maximum recursion depth exceeded in comparison
--
Terry Jan Reedy
More information about the Python-ideas
mailing list