[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