Issue #26823: Abbreviate recursive tracebacks

Large sections of repeated lines in tracebacks are now abbreviated as
"[Previous line repeated {count} more times]" by both the traceback
module and the builtin traceback rendering.

Patch by Emanuel Barry.
This commit is contained in:
Nick Coghlan 2016-08-15 13:11:34 +10:00
parent d61a2e75b5
commit d00342347e
6 changed files with 222 additions and 4 deletions

View file

@ -412,6 +412,11 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
{
int err = 0;
long depth = 0;
PyObject *last_file = NULL;
int last_line = -1;
PyObject *last_name = NULL;
long cnt = 0;
PyObject *line;
PyTracebackObject *tb1 = tb;
while (tb1 != NULL) {
depth++;
@ -419,16 +424,39 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
}
while (tb != NULL && err == 0) {
if (depth <= limit) {
err = tb_displayline(f,
tb->tb_frame->f_code->co_filename,
tb->tb_lineno,
tb->tb_frame->f_code->co_name);
if (last_file != NULL &&
tb->tb_frame->f_code->co_filename == last_file &&
last_line != -1 && tb->tb_lineno == last_line &&
last_name != NULL &&
tb->tb_frame->f_code->co_name == last_name) {
cnt++;
} else {
if (cnt > 3) {
line = PyUnicode_FromFormat(
" [Previous line repeated %d more times]\n", cnt-3);
err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
}
last_file = tb->tb_frame->f_code->co_filename;
last_line = tb->tb_lineno;
last_name = tb->tb_frame->f_code->co_name;
cnt = 0;
}
if (cnt < 3)
err = tb_displayline(f,
tb->tb_frame->f_code->co_filename,
tb->tb_lineno,
tb->tb_frame->f_code->co_name);
}
depth--;
tb = tb->tb_next;
if (err == 0)
err = PyErr_CheckSignals();
}
if (cnt > 3) {
line = PyUnicode_FromFormat(
" [Previous line repeated %d more times]\n", cnt-3);
err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
}
return err;
}