diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/traceback.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/Python/traceback.c b/Python/traceback.c index 439689b32a..de658b9103 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -592,7 +592,6 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent, * Traceback (most recent call last): * File "/home/isidentical/cpython/cpython/t.py", line 10, in <module> * add_values(1, 2, 'x', 3, 4) - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * File "/home/isidentical/cpython/cpython/t.py", line 2, in add_values * return a + b + c + d + e * ~~~~~~^~~ @@ -736,7 +735,7 @@ print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py int special_chars = (left_end_offset != -1 || right_start_offset != -1); const char *str; while (++offset <= end_offset) { - if (offset <= start_offset || offset > end_offset) { + if (offset <= start_offset) { str = " "; } else if (special_chars && left_end_offset < offset && offset <= right_start_offset) { str = secondary; @@ -792,6 +791,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen int code_offset = tb->tb_lasti; PyCodeObject* code = frame->f_frame->f_code; + const Py_ssize_t source_line_len = PyUnicode_GET_LENGTH(source_line); int start_line; int end_line; @@ -813,7 +813,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen // // ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE // ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~ - // | |-> left_end_offset | |-> left_offset + // | |-> left_end_offset | |-> end_offset // |-> start_offset |-> right_start_offset // // In general we will only have (start_offset, end_offset) but we can gather more information @@ -822,6 +822,9 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen // the different ranges (primary_error_char and secondary_error_char). If we cannot obtain the // AST information or we cannot identify special ranges within it, then left_end_offset and // right_end_offset will be set to -1. + // + // To keep the column indicators pertinent, they are not shown when the primary character + // spans the whole line. // Convert the utf-8 byte offset to the actual character offset so we print the right number of carets. assert(source_line); @@ -859,7 +862,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen goto done; } - Py_ssize_t i = PyUnicode_GET_LENGTH(source_line); + Py_ssize_t i = source_line_len; while (--i >= 0) { if (!IS_WHITESPACE(source_line_str[i])) { break; @@ -869,6 +872,13 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen end_offset = i + 1; } + // Elide indicators if primary char spans the frame line + Py_ssize_t stripped_line_len = source_line_len - truncation - _TRACEBACK_SOURCE_LINE_INDENT; + bool has_secondary_ranges = (left_end_offset != -1 || right_start_offset != -1); + if (end_offset - start_offset == stripped_line_len && !has_secondary_ranges) { + goto done; + } + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { err = -1; goto done; |