From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:12:39 +0000 (+0100) Subject: [3.13] gh-128894: Fix `TracebackException._format_syntax_error` on custom `SyntaxErro... X-Git-Tag: v3.13.2~59 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f6e80a03ec2f6328aaaff4ea6598fb6cafbafda;p=thirdparty%2FPython%2Fcpython.git [3.13] gh-128894: Fix `TracebackException._format_syntax_error` on custom `SyntaxError` metadata (GH-128946) (#129178) --- diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index bbb38291e22b..2f543bccf566 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -376,6 +376,30 @@ class TracebackCases(unittest.TestCase): ' ValueError: 0\n', ]) + def test_format_exception_group_syntax_error_with_custom_values(self): + # See https://github.com/python/cpython/issues/128894 + for exc in [ + SyntaxError('error', 'abcd'), + SyntaxError('error', [None] * 4), + SyntaxError('error', (1, 2, 3, 4)), + SyntaxError('error', (1, 2, 3, 4)), + SyntaxError('error', (1, 'a', 'b', 2)), + # with end_lineno and end_offset: + SyntaxError('error', 'abcdef'), + SyntaxError('error', [None] * 6), + SyntaxError('error', (1, 2, 3, 4, 5, 6)), + SyntaxError('error', (1, 'a', 'b', 2, 'c', 'd')), + ]: + with self.subTest(exc=exc): + err = traceback.format_exception_only(exc, show_group=True) + # Should not raise an exception: + if exc.lineno is not None: + self.assertEqual(len(err), 2) + self.assertTrue(err[0].startswith(' File')) + else: + self.assertEqual(len(err), 1) + self.assertEqual(err[-1], 'SyntaxError: error\n') + @requires_subprocess() @force_not_colorized def test_encoded_file(self): diff --git a/Lib/traceback.py b/Lib/traceback.py index 947c3e82b8c0..f5e054190eaf 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1283,7 +1283,7 @@ class TracebackException: filename_suffix = ' ({})'.format(self.filename) text = self.text - if text is not None: + if isinstance(text, str): # text = " foo\n" # rtext = " foo" # ltext = "foo" @@ -1292,10 +1292,17 @@ class TracebackException: spaces = len(rtext) - len(ltext) if self.offset is None: yield ' {}\n'.format(ltext) - else: + elif isinstance(self.offset, int): offset = self.offset if self.lineno == self.end_lineno: - end_offset = self.end_offset if self.end_offset not in {None, 0} else offset + end_offset = ( + self.end_offset + if ( + isinstance(self.end_offset, int) + and self.end_offset != 0 + ) + else offset + ) else: end_offset = len(rtext) + 1 diff --git a/Misc/NEWS.d/next/Library/2025-01-17-17-20-51.gh-issue-128894.gX1-8J.rst b/Misc/NEWS.d/next/Library/2025-01-17-17-20-51.gh-issue-128894.gX1-8J.rst new file mode 100644 index 000000000000..7e015103a957 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-01-17-17-20-51.gh-issue-128894.gX1-8J.rst @@ -0,0 +1,2 @@ +Fix ``traceback.TracebackException._format_syntax_error`` not to fail on +exceptions with custom metadata.