[Python-ideas] Have REPL print less by default
Steven D'Aprano
steve at pearwood.info
Tue Apr 19 12:18:58 EDT 2016
On Tue, Apr 19, 2016 at 11:12:16PM +1000, Nick Coghlan wrote:
> The default REPL behaviour is appropriate for this "somewhat experienced
> Pythonista tinkering with code to see how it behaves" use case - keeping
> the results very close to what they would be if you typed the same line of
> code into a text file and ran it that way. It's not necessarily the best
> way to *learn* those equivalences, but that's also not what it's designed
> for.
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:
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
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 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
[...repeat previous line 197 times...]
File "<stdin>", line 2, in fact
RuntimeError: maximum recursion depth exceeded in comparison
--
Steve
More information about the Python-ideas
mailing list