summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2016-08-15 03:11:34 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2016-08-15 03:11:34 (GMT)
commitd00342347e467981b52368235b99a22dc264dab1 (patch)
treee7ea356a2c4e93f592fd7f3e52e12dfeccfaf13e /Python
parentd61a2e75b5218f0f89b4f623713004edb9512180 (diff)
downloadcpython-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.c36
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;
}