From: Russel Webber <24542073+RusselWebber@users.noreply.github.com> Date: Thu, 27 Jan 2022 14:13:12 +0000 (+0000) Subject: bpo-46098: Add test for multiline syntax error traceback (GH-30695) X-Git-Tag: v3.11.0a5~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=183f8d57fa5959e7578e7f470edc364edb23caca;p=thirdparty%2FPython%2Fcpython.git bpo-46098: Add test for multiline syntax error traceback (GH-30695) --- diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index e0884fb9b781..0aa76aeb4ce0 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -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