diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2016-08-15 03:11:34 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2016-08-15 03:11:34 (GMT) |
commit | d00342347e467981b52368235b99a22dc264dab1 (patch) | |
tree | e7ea356a2c4e93f592fd7f3e52e12dfeccfaf13e /Python | |
parent | d61a2e75b5218f0f89b4f623713004edb9512180 (diff) | |
download | cpython-d00342347e467981b52368235b99a22dc264dab1.zip cpython-d00342347e467981b52368235b99a22dc264dab1.tar.gz cpython-d00342347e467981b52368235b99a22dc264dab1.tar.bz2 |
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.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/traceback.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/Python/traceback.c b/Python/traceback.c index 59552ca..15cde44 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -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; } |