Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 162d3d4

Browse files
authored
gh-112620: Fix dis error on show_cache with labels (#112621)
1 parent 4ed46d2 commit 162d3d4

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

Lib/dis.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,15 +412,14 @@ def _create(cls, op, arg, offset, start_offset, starts_line, line_number,
412412
co_consts=None, varname_from_oparg=None, names=None,
413413
labels_map=None, exceptions_map=None):
414414

415-
label_width = 4 + len(str(len(labels_map)))
416415
argval, argrepr = cls._get_argval_argrepr(
417416
op, arg, offset,
418417
co_consts, names, varname_from_oparg, labels_map)
419418
label = labels_map.get(offset, None)
420419
instr = Instruction(_all_opname[op], op, arg, argval, argrepr,
421420
offset, start_offset, starts_line, line_number,
422421
label, positions)
423-
instr.label_width = label_width
422+
instr.label_width = 4 + len(str(len(labels_map)))
424423
instr.exc_handler = exceptions_map.get(offset, None)
425424
return instr
426425

@@ -468,12 +467,14 @@ def is_jump_target(self):
468467
"""True if other code jumps to here, otherwise False"""
469468
return self.label is not None
470469

471-
def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0):
470+
def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0,
471+
label_width=0):
472472
"""Format instruction details for inclusion in disassembly output.
473473
474474
*lineno_width* sets the width of the line number field (0 omits it)
475475
*mark_as_current* inserts a '-->' marker arrow as part of the line
476476
*offset_width* sets the width of the instruction offset field
477+
*label_width* sets the width of the label field
477478
"""
478479
fields = []
479480
# Column: Source code line number
@@ -488,9 +489,9 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0):
488489
# Column: Label
489490
if self.label is not None:
490491
lbl = f"L{self.label}:"
491-
fields.append(f"{lbl:>{self.label_width}}")
492+
fields.append(f"{lbl:>{label_width}}")
492493
else:
493-
fields.append(' ' * self.label_width)
494+
fields.append(' ' * label_width)
494495
# Column: Instruction offset from start of code sequence
495496
if offset_width > 0:
496497
fields.append(f"{repr(self.offset):>{offset_width}} ")
@@ -648,6 +649,7 @@ def make_labels_map(original_code, exception_entries):
648649
return labels_map
649650

650651
labels_map = make_labels_map(original_code, exception_entries)
652+
label_width = 4 + len(str(len(labels_map)))
651653

652654
exceptions_map = {}
653655
for start, end, target, _, _ in exception_entries:
@@ -756,6 +758,7 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
756758
else:
757759
offset_width = 0
758760

761+
label_width = -1
759762
for instr in _get_instructions_bytes(code, varname_from_oparg, names,
760763
co_consts, linestarts,
761764
line_offset=line_offset,
@@ -774,7 +777,9 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
774777
# Each CACHE takes 2 bytes
775778
is_current_instr = instr.offset <= lasti \
776779
<= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)])
777-
print(instr._disassemble(lineno_width, is_current_instr, offset_width),
780+
label_width = getattr(instr, 'label_width', label_width)
781+
assert label_width >= 0
782+
print(instr._disassemble(lineno_width, is_current_instr, offset_width, label_width),
778783
file=file)
779784
if exception_entries:
780785
print("ExceptionTable:", file=file)

Lib/test/test_dis.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,18 @@ def test_oparg_alias(self):
18961896
positions=None)
18971897
self.assertEqual(instruction.arg, instruction.oparg)
18981898

1899+
def test_show_caches_with_label(self):
1900+
def f(x, y, z):
1901+
if x:
1902+
res = y
1903+
else:
1904+
res = z
1905+
return res
1906+
1907+
output = io.StringIO()
1908+
dis.dis(f.__code__, file=output, show_caches=True)
1909+
self.assertIn("L1:", output.getvalue())
1910+
18991911
def test_baseopname_and_baseopcode(self):
19001912
# Standard instructions
19011913
for name, code in dis.opmap.items():

0 commit comments

Comments
 (0)