From 8023ff3f1fc6981071fde13fb7b47982adfa7d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:13:37 +0200 Subject: [PATCH 1/6] Handle an empty AST body when reporting tracebacks. --- Lib/traceback.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/traceback.py b/Lib/traceback.py index 6ee1a50ca6804a..eba6f03a3c6de3 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -698,6 +698,8 @@ def _should_show_carets(self, start_offset, end_offset, all_lines, anchors): with suppress(SyntaxError, ImportError): import ast tree = ast.parse('\n'.join(all_lines)) + if not tree.body: + return False statement = tree.body[0] value = None def _spawns_full_line(value): From 94be00e668aa8e82c72a0b789751928c17769cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:35:28 +0200 Subject: [PATCH 2/6] add tests --- Lib/test/test_traceback.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 1895c88d23b70d..daad9a09cf1202 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -3275,6 +3275,17 @@ def format_frame_summary(self, frame_summary, colorize=False): f' File "{__file__}", line {lno}, in f\n 1/0\n' ) + def test_traceback_empty_ast(self): + # see gh-122145 + fs = traceback.FrameSummary("?", 1, "s", lookup_line=False, + locals=None, end_lineno=1, colno=0, + end_colno=10, line="#123456789") + self.assertListEqual( + traceback.StackSummary().format_frame_summary(fs).splitlines(), + [' File "?", line 1, in s', ' #123456789'] + ) + + class Unrepresentable: def __repr__(self) -> str: raise Exception("Unrepresentable") From 0925ed2b25689de6f5a8d5753df05b70d0505406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:38:25 +0200 Subject: [PATCH 3/6] blurb --- .../next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst diff --git a/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst b/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst new file mode 100644 index 00000000000000..740ebda26bb5fc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst @@ -0,0 +1,2 @@ +Fix an issue when reporting tracebacks containing only Python comments. +Patch by Bénédikt Tran. From b98e162fc9625b7ce4bf29128300c764dbd6b3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:11:42 +0200 Subject: [PATCH 4/6] Update NEWS entry. --- .../Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst b/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst index 740ebda26bb5fc..a4282f12d9742a 100644 --- a/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst +++ b/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst @@ -1,2 +1,3 @@ -Fix an issue when reporting tracebacks containing only Python comments. -Patch by Bénédikt Tran. +Fix an issue when reporting tracebacks corresponding to Python code +emitting an empty AST body. +Patch by Nikita Sobolev and Bénédikt Tran. From 9bc84473472f2dce64a7f205c9ffe008260460ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:30:44 +0200 Subject: [PATCH 5/6] update tests --- Lib/test/test_traceback.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index daad9a09cf1202..cc980e96fae7ed 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -3275,16 +3275,15 @@ def format_frame_summary(self, frame_summary, colorize=False): f' File "{__file__}", line {lno}, in f\n 1/0\n' ) - def test_traceback_empty_ast(self): - # see gh-122145 - fs = traceback.FrameSummary("?", 1, "s", lookup_line=False, - locals=None, end_lineno=1, colno=0, - end_colno=10, line="#123456789") - self.assertListEqual( - traceback.StackSummary().format_frame_summary(fs).splitlines(), - [' File "?", line 1, in s', ' #123456789'] - ) - + def test_summary_should_show_carets(self): + # See: https://github.com/python/cpython/issues/122353 + should_show = traceback.StackSummary()._should_show_carets + # a line that may or may not have carrets shown + self.assertTrue(should_show(0, 1, ['a = 123456789'], None)) + self.assertFalse(should_show(0, 999, ['return'], None)) + # commented lines have an empty AST body, hence never shown + self.assertFalse(should_show(0, 1, ['# abc = 123456789'], None)) + self.assertFalse(should_show(0, 999, ['# return'], None)) class Unrepresentable: def __repr__(self) -> str: From c944dae5a26c4bade7df4e2e09fba2067b71d29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:33:22 +0200 Subject: [PATCH 6/6] update test --- Lib/test/test_traceback.py | 39 +++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index cc980e96fae7ed..e6311ce6b35b31 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -3277,13 +3277,38 @@ def format_frame_summary(self, frame_summary, colorize=False): def test_summary_should_show_carets(self): # See: https://github.com/python/cpython/issues/122353 - should_show = traceback.StackSummary()._should_show_carets - # a line that may or may not have carrets shown - self.assertTrue(should_show(0, 1, ['a = 123456789'], None)) - self.assertFalse(should_show(0, 999, ['return'], None)) - # commented lines have an empty AST body, hence never shown - self.assertFalse(should_show(0, 1, ['# abc = 123456789'], None)) - self.assertFalse(should_show(0, 999, ['# return'], None)) + + # statement to execute and to get a ZeroDivisionError for a traceback + statement = "abcdef = 1 / 0 and 2.0" + colno = statement.index('1 / 0') + end_colno = colno + len('1 / 0') + + # Actual line to use when rendering the traceback + # and whose AST will be extracted (it will be empty). + cached_line = '# this line will be used during rendering' + self.addCleanup(unlink, TESTFN) + with open(TESTFN, "w") as file: + file.write(cached_line) + linecache.updatecache(TESTFN, {}) + + try: + exec(compile(statement, TESTFN, "exec")) + except ZeroDivisionError as exc: + # This is the simplest way to create a StackSummary + # whose FrameSummary items have their column offsets. + s = traceback.TracebackException.from_exception(exc).stack + self.assertIsInstance(s, traceback.StackSummary) + with unittest.mock.patch.object(s, '_should_show_carets', + wraps=s._should_show_carets) as ff: + self.assertEqual(len(s), 2) + self.assertListEqual( + s.format_frame_summary(s[1]).splitlines(), + [ + f' File "{TESTFN}", line 1, in ', + f' {cached_line}' + ] + ) + ff.assert_called_with(colno, end_colno, [cached_line], None) class Unrepresentable: def __repr__(self) -> str: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy