mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
[3.11] gh-93883: elide traceback indicators when possible (GH-93994) (GH-94740)
Elide traceback column indicators when the entire line of the frame is implicated. This reduces traceback length and draws more attention to the remaining (very relevant) indicators. Example: ``` Traceback (most recent call last): File "query.py", line 99, in <module> bar() File "query.py", line 66, in bar foo() File "query.py", line 37, in foo magic_arithmetic('foo') File "query.py", line 18, in magic_arithmetic return add_counts(x) / 25 ^^^^^^^^^^^^^ File "query.py", line 24, in add_counts return 25 + query_user(user1) + query_user(user2) ^^^^^^^^^^^^^^^^^ File "query.py", line 32, in query_user return 1 + query_count(db, response['a']['b']['c']['user'], retry=True) ~~~~~~~~~~~~~~~~~~^^^^^ TypeError: 'NoneType' object is not subscriptable ``` Automerge-Triggered-By: GH:pablogsal
This commit is contained in:
parent
f3212b1ec7
commit
45896f2a02
9 changed files with 111 additions and 139 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue