Skip to content

Commit 99dc089

Browse files
[3.13] pythongh-122145: Handle an empty AST body when reporting tracebacks (pythonGH-122161) (python#124214)
pythongh-122145: Handle an empty AST body when reporting tracebacks (pythonGH-122161) (cherry picked from commit 5cd50cb) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent 5dcce94 commit 99dc089

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

Lib/test/test_traceback.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,6 +3304,41 @@ def format_frame_summary(self, frame_summary, colorize=False):
33043304
f' File "{__file__}", line {lno}, in f\n 1/0\n'
33053305
)
33063306

3307+
def test_summary_should_show_carets(self):
3308+
# See: https://github.com/python/cpython/issues/122353
3309+
3310+
# statement to execute and to get a ZeroDivisionError for a traceback
3311+
statement = "abcdef = 1 / 0 and 2.0"
3312+
colno = statement.index('1 / 0')
3313+
end_colno = colno + len('1 / 0')
3314+
3315+
# Actual line to use when rendering the traceback
3316+
# and whose AST will be extracted (it will be empty).
3317+
cached_line = '# this line will be used during rendering'
3318+
self.addCleanup(unlink, TESTFN)
3319+
with open(TESTFN, "w") as file:
3320+
file.write(cached_line)
3321+
linecache.updatecache(TESTFN, {})
3322+
3323+
try:
3324+
exec(compile(statement, TESTFN, "exec"))
3325+
except ZeroDivisionError as exc:
3326+
# This is the simplest way to create a StackSummary
3327+
# whose FrameSummary items have their column offsets.
3328+
s = traceback.TracebackException.from_exception(exc).stack
3329+
self.assertIsInstance(s, traceback.StackSummary)
3330+
with unittest.mock.patch.object(s, '_should_show_carets',
3331+
wraps=s._should_show_carets) as ff:
3332+
self.assertEqual(len(s), 2)
3333+
self.assertListEqual(
3334+
s.format_frame_summary(s[1]).splitlines(),
3335+
[
3336+
f' File "{TESTFN}", line 1, in <module>',
3337+
f' {cached_line}'
3338+
]
3339+
)
3340+
ff.assert_called_with(colno, end_colno, [cached_line], None)
3341+
33073342
class Unrepresentable:
33083343
def __repr__(self) -> str:
33093344
raise Exception("Unrepresentable")

Lib/traceback.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ def _should_show_carets(self, start_offset, end_offset, all_lines, anchors):
698698
with suppress(SyntaxError, ImportError):
699699
import ast
700700
tree = ast.parse('\n'.join(all_lines))
701+
if not tree.body:
702+
return False
701703
statement = tree.body[0]
702704
value = None
703705
def _spawns_full_line(value):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix an issue when reporting tracebacks corresponding to Python code
2+
emitting an empty AST body.
3+
Patch by Nikita Sobolev and Bénédikt Tran.

0 commit comments

Comments
 (0)