Skip to content

gh-103046: Display current line correctly for dis.disco() with CACHE entries #103047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Lib/dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,12 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
instr.offset > 0)
if new_source_line:
print(file=file)
is_current_instr = instr.offset == lasti
if show_caches:
is_current_instr = instr.offset == lasti
else:
# Each CACHE takes 2 bytes
is_current_instr = instr.offset <= lasti \
<= instr.offset + 2 * _inline_cache_entries[_deoptop(instr.opcode)]
print(instr._disassemble(lineno_width, is_current_instr, offset_width),
file=file)
if exception_entries:
Expand Down
29 changes: 29 additions & 0 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,35 @@ def test_show_caches(self):
self.assertEqual(caches.count(""), empty_caches)
self.assertEqual(len(caches), total_caches)

@cpython_only
def test_show_currinstr_with_cache(self):
"""
Make sure that with lasti pointing to CACHE, it still shows the current
line correctly
"""
def f():
print(a)
# The code above should generate a LOAD_GLOBAL which has CACHE instr after
# However, this might change in the future. So we explicitly try to find
# a CACHE entry in the instructions. If we can't do that, fail the test

for inst in dis.get_instructions(f, show_caches=True):
if inst.opname == "CACHE":
op_offset = inst.offset - 2
cache_offset = inst.offset
break
else:
self.fail("Can't find a CACHE entry in the function provided to do the test")

assem_op = self.get_disassembly(f.__code__, lasti=op_offset, wrapper=False)
assem_cache = self.get_disassembly(f.__code__, lasti=cache_offset, wrapper=False)

# Make sure --> exists and points to the correct offset
self.assertRegex(assem_op, fr"-->\s+{op_offset}")
# Make sure when lasti points to cache, it shows the same disassembly
self.assertEqual(assem_op, assem_cache)


class DisWithFileTests(DisTests):

# Run the tests again, using the file arg instead of print
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Display current line label correctly in :mod:`dis` when ``show_caches`` is False and ``lasti`` points to a CACHE entry.