bpo-46098: Add test for multiline syntax error traceback (GH-30695)

This commit is contained in:
Russel Webber 2022-01-27 14:13:12 +00:00 committed by GitHub
parent aa78287bc6
commit 183f8d57fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 41 additions and 7 deletions

View File

@ -460,6 +460,42 @@ class TracebackErrorLocationCaretTests(unittest.TestCase):
result_lines = self.get_exception(f_with_multiline)
self.assertEqual(result_lines, expected_f.splitlines())
def test_caret_multiline_expression_syntax_error(self):
# Make sure an expression spanning multiple lines that has
# a syntax error is correctly marked with carets.
code = textwrap.dedent("""
def foo(*args, **kwargs):
pass
a, b, c = 1, 2, 3
foo(a, z
for z in
range(10), b, c)
""")
def f_with_multiline():
# Need to defer the compilation until in self.get_exception(..)
return compile(code, "?", "exec")
lineno_f = f_with_multiline.__code__.co_firstlineno
expected_f = (
'Traceback (most recent call last):\n'
f' File "{__file__}", line {self.callable_line}, in get_exception\n'
' callable()\n'
' ^^^^^^^^^^\n'
f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n'
' return compile(code, "?", "exec")\n'
' ^^^^^^^^^^^^^^^^^^^^^^^^^^\n'
' File "?", line 7\n'
' foo(a, z\n'
' ^'
)
result_lines = self.get_exception(f_with_multiline)
self.assertEqual(result_lines, expected_f.splitlines())
def test_caret_multiline_expression_bin_op(self):
# Make sure no carets are printed for expressions spanning multiple
# lines.
@ -672,16 +708,14 @@ class CPythonTracebackErrorCaretTests(TracebackErrorLocationCaretTests):
Same set of tests as above but with Python's internal traceback printing.
"""
def get_exception(self, callable):
from _testcapi import traceback_print
from _testcapi import exception_print
try:
callable()
self.fail("No exception thrown.")
except:
type_, value, tb = sys.exc_info()
file_ = StringIO()
traceback_print(tb, file_)
return file_.getvalue().splitlines()
except Exception as e:
with captured_output("stderr") as tbstderr:
exception_print(e)
return tbstderr.getvalue().splitlines()[:-1]
callable_line = get_exception.__code__.co_firstlineno + 3