Skip to content

Commit 34eb6f7

Browse files
gh-103046: Display current line correctly for dis.disco() with CACHE entries (#103047)
1 parent 3606753 commit 34eb6f7

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

Lib/dis.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,12 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
581581
instr.offset > 0)
582582
if new_source_line:
583583
print(file=file)
584-
is_current_instr = instr.offset == lasti
584+
if show_caches:
585+
is_current_instr = instr.offset == lasti
586+
else:
587+
# Each CACHE takes 2 bytes
588+
is_current_instr = instr.offset <= lasti \
589+
<= instr.offset + 2 * _inline_cache_entries[_deoptop(instr.opcode)]
585590
print(instr._disassemble(lineno_width, is_current_instr, offset_width),
586591
file=file)
587592
if exception_entries:

Lib/test/test_dis.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,35 @@ def test_show_caches(self):
11981198
self.assertEqual(caches.count(""), empty_caches)
11991199
self.assertEqual(len(caches), total_caches)
12001200

1201+
@cpython_only
1202+
def test_show_currinstr_with_cache(self):
1203+
"""
1204+
Make sure that with lasti pointing to CACHE, it still shows the current
1205+
line correctly
1206+
"""
1207+
def f():
1208+
print(a)
1209+
# The code above should generate a LOAD_GLOBAL which has CACHE instr after
1210+
# However, this might change in the future. So we explicitly try to find
1211+
# a CACHE entry in the instructions. If we can't do that, fail the test
1212+
1213+
for inst in dis.get_instructions(f, show_caches=True):
1214+
if inst.opname == "CACHE":
1215+
op_offset = inst.offset - 2
1216+
cache_offset = inst.offset
1217+
break
1218+
else:
1219+
self.fail("Can't find a CACHE entry in the function provided to do the test")
1220+
1221+
assem_op = self.get_disassembly(f.__code__, lasti=op_offset, wrapper=False)
1222+
assem_cache = self.get_disassembly(f.__code__, lasti=cache_offset, wrapper=False)
1223+
1224+
# Make sure --> exists and points to the correct offset
1225+
self.assertRegex(assem_op, fr"-->\s+{op_offset}")
1226+
# Make sure when lasti points to cache, it shows the same disassembly
1227+
self.assertEqual(assem_op, assem_cache)
1228+
1229+
12011230
class DisWithFileTests(DisTests):
12021231

12031232
# Run the tests again, using the file arg instead of print
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Display current line label correctly in :mod:`dis` when ``show_caches`` is False and ``lasti`` points to a CACHE entry.

0 commit comments

Comments
 (0)