8000 gh-123123: Fix display of syntax errors covering multiple lines (#123… · python/cpython@48856ea · GitHub
[go: up one dir, main page]

Skip to content

Commit 48856ea

Browse files
authored
gh-123123: Fix display of syntax errors covering multiple lines (#123131)
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
1 parent b6d0a40 commit 48856ea

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

Lib/test/test_traceback.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,35 @@ def f_with_multiline():
699699
result_lines = self.get_exception(f_with_multiline)
700700
self.assertEqual(result_lines, expected_f.splitlines())
701701

702+
# Check custom error messages covering multiple lines
703+
code = textwrap.dedent("""
704+
dummy_call(
705+
"dummy value"
706+
foo="bar",
707+
)
708+
""")
709+
710+
def f_with_multiline():
711+
# Need to defer the compilation until in self.get_exception(..)
712+
return compile(code, "?", "exec")
713+
714+
lineno_f = f_with_multiline.__code__.co_firstlineno
715+
716+
expected_f = (
717+
'Traceback (most recent call last):\n'
718+
f' File "{__file__}", line {self.callable_line}, in get_exception\n'
719+
' callable()\n'
720+
' ~~~~~~~~^^\n'
721+
f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n'
722+
' return compile(code, "?", "exec")\n'
723+
' File "?", line 3\n'
724+
' "dummy value"\n'
725+
' ^^^^^^^^^^^^^'
726+
)
727+
728+
result_lines = self.get_exception(f_with_multiline)
729+
self.assertEqual(result_lines, expected_f.splitlines())
730+
702731
def test_caret_multiline_expression_bin_op(self):
703732
# Make sure no carets are printed for expressions spanning multiple
704733
# lines.
@@ -2312,19 +2341,22 @@ def test_message_none(self):
23122341
def test_syntax_error_various_offsets(self):
23132342
for offset in range(-5, 10):
23142343
for add in [0, 2]:
2315-
text = " "*add + "text%d" % offset
2344+
text = " " * add + "text%d" % offset
23162345
expected = [' File "file.py", line 1']
23172346
if offset < 1:
23182347
expected.append(" %s" % text.lstrip())
23192348
elif offset <= 6:
23202349
expected.append(" %s" % text.lstrip())
2321-
expected.append(" %s^" % (" "*(offset-1)))
2350+
# Set the caret length to match the length of the text minus the offset.
2351+
caret_length = max(1, len(text.lstrip()) - offset + 1)
2352+
expected.append(" %s%s" % (" " * (offset - 1), "^" * caret_length))
23222353
else:
2354+
caret_length = max(1, len(text.lstrip()) - 4)
23232355
expected.append(" %s" % text.lstrip())
2324-
expected.append(" %s^" % (" "*5))
2356+
expected.append(" %s%s" % (" " * 5, "^" * caret_length))
23252357
expected.append("SyntaxError: msg")
23262358
expected.append("")
2327-
err = self.get_report(SyntaxError("msg", ("file.py", 1, offset+add, text)))
2359+
err = self.get_report(SyntaxError("msg", ("file.py", 1, offset + add, text)))
23282360
exp = "\n".join(expected)
23292361
self.assertEqual(exp, err)
23302362

Lib/traceback.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,11 +1292,15 @@ def _format_syntax_error(self, stype, **kwargs):
12921292
yield ' {}\n'.format(ltext)
12931293
else:
12941294
offset = self.offset
1295-
end_offset = self.end_offset if self.end_offset not in {None, 0} else offset
1295+
if self.lineno == self.end_lineno:
1296+
end_offset = self.end_offset if self.end_offset not in {None, 0} else offset
1297+
else:
1298+
end_offset = len(rtext) + 1
1299+
12961300
if self.text and offset > len(self.text):
1297-
offset = len(self.text) + 1
1301+
offset = len(rtext) + 1
12981302
if self.text and end_offset > len(self.text):
1299-
end_offset = len(self.text) + 1
1303+
end_offset = len(rtext) + 1
13001304
if offset >= end_offset or end_offset < 0:
13011305
end_offset = offset + 1
13021306

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix displaying :exc:`SyntaxError` exceptions covering multiple lines. Patch
2+
by Pablo Galindo

0 commit comments

Comments
 (0)
0