From 5470f75fda4372adbce80cd2046402ea0965ed05 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 15 Nov 2023 22:08:39 +0000 Subject: [PATCH 01/24] Instruction gets the label --- Lib/dis.py | 34 ++-- Lib/test/test_dis.py | 368 +++++++++++++++++++++---------------------- 2 files changed, 206 insertions(+), 196 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 965a0268635ebc..d934caf5066870 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -263,10 +263,10 @@ def show_code(co, *, file=None): 'start_offset', 'starts_line', 'line_number', - 'is_jump_target', + 'label', 'positions' ], - defaults=[None] + defaults=[None, None] ) _Instruction.opname.__doc__ = "Human readable name for operation" @@ -281,7 +281,7 @@ def show_code(co, *, file=None): ) _Instruction.starts_line.__doc__ = "True if this opcode starts a source line, otherwise False" _Instruction.line_number.__doc__ = "source line number associated with this opcode (if any), otherwise None" -_Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False" +_Instruction.label.__doc__ = "A label (int > 0) if this instruction is a jump target, otherwise None" _Instruction.positions.__doc__ = "dis.Positions object holding the span of source code covered by this instruction" _ExceptionTableEntry = collections.namedtuple("_ExceptionTableEntry", @@ -325,7 +325,7 @@ class Instruction(_Instruction): otherwise equal to Instruction.offset starts_line - True if this opcode starts a source line, otherwise False line_number - source line number associated with this opcode (if any), otherwise None - is_jump_target - True if other code jumps to here, otherwise False + label - A label (int > 0) if this instruction is a jump target, otherwise None positions - Optional dis.Positions object holding the span of source code covered by this instruction """ @@ -399,14 +399,14 @@ def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg): @classmethod def _create(cls, op, arg, offset, start_offset, starts_line, line_number, - is_jump_target, positions, + label, positions, co_consts=None, varname_from_oparg=None, names=None): argval, argrepr = cls._get_argval_argrepr( op, arg, offset, co_consts, names, varname_from_oparg) return Instruction(_all_opname[op], op, arg, argval, argrepr, offset, start_offset, starts_line, line_number, - is_jump_target, positions) + label, positions) @property def oparg(self): @@ -447,6 +447,11 @@ def jump_target(self): """ return _get_jump_target(self.opcode, self.arg, self.offset) + @property + def is_jump_target(self): + """True if other code jumps to here, otherwise False""" + return self.label is not None + def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): """Format instruction details for inclusion in disassembly output. @@ -605,10 +610,16 @@ def _get_instructions_bytes(code, varname_from_oparg=None, original_code = original_code or code co_positions = co_positions or iter(()) get_name = None if names is None else names.__getitem__ - labels = set(findlabels(original_code)) - for start, end, target, _, _ in exception_entries: - for i in range(start, end): - labels.add(target) + + def make_labels_map(original_code, exception_entries): + labels = set(findlabels(original_code)) + for start, end, target, _, _ in exception_entries: + for i in range(start, end): + labels.add(target) + return {offset: i+1 for (i, offset) in enumerate(sorted(labels))} + + labels_map = make_labels_map(original_code, exception_entries) + starts_line = False local_line_number = None line_number = None @@ -621,13 +632,12 @@ def _get_instructions_bytes(code, varname_from_oparg=None, line_number = local_line_number + line_offset else: line_number = None - is_jump_target = offset in labels positions = Positions(*next(co_positions, ())) deop = _deoptop(op) op = code[offset] yield Instruction._create(op, arg, offset, start_offset, starts_line, line_number, - is_jump_target, positions, co_consts=co_consts, + labels_map.get(offset, None), positions, co_consts=co_consts, varname_from_oparg=varname_from_oparg, names=names) caches = _get_cache_size(_all_opname[deop]) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 43debdcf6e1607..34c6ab5891a5ae 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1637,197 +1637,197 @@ def _prepare_test_cases(): Instruction = dis.Instruction expected_opinfo_outer = [ - Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='BUILD_TUPLE', opcode=52, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=110, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=1, argrepr='1', offset=40, start_offset=40, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='BUILD_LIST', opcode=47, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='BUILD_MAP', opcode=48, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=52, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=1, argrepr='1', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='BUILD_LIST', opcode=47, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='BUILD_MAP', opcode=48, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None), + Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None), ] expected_opinfo_f = [ - Instruction(opname='COPY_FREE_VARS', opcode=62, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='BUILD_TUPLE', opcode=52, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=110, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, is_jump_target=False, positions=None), + Instruction(opname='COPY_FREE_VARS', opcode=62, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=52, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None), + Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None), ] expected_opinfo_inner = [ - Instruction(opname='COPY_FREE_VARS', opcode=62, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=84, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=88, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='COPY_FREE_VARS', opcode=62, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=88, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None), ] expected_opinfo_jumpy = [ - Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, is_jump_target=True, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, is_jump_target=False, positions=None), - Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=102, start_offset=102, starts_line=False, line_number=10, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST_CHECK', opcode=87, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, is_jump_target=True, positions=None), - Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to 206', offset=122, start_offset=122, starts_line=False, line_number=11, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=True, line_number=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=1, argrepr='1', offset=150, start_offset=150, starts_line=False, line_number=13, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=45, arg=23, argval=23, argrepr='-=', offset=152, start_offset=152, starts_line=False, line_number=13, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=False, line_number=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, is_jump_target=True, positions=None), - Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=19, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=30, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=True, line_number=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=1, argrepr='1', offset=230, start_offset=230, starts_line=True, line_number=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=7, argval=0, argrepr='0', offset=232, start_offset=232, starts_line=False, line_number=21, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=45, arg=11, argval=11, argrepr='/', offset=234, start_offset=234, starts_line=False, line_number=21, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=240, start_offset=240, starts_line=True, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=2, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=110, arg=1, argval='dodgy', argrepr='dodgy', offset=244, start_offset=244, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=246, start_offset=246, starts_line=True, line_number=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=256, start_offset=256, starts_line=False, line_number=26, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=258, start_offset=258, starts_line=False, line_number=26, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=268, start_offset=268, starts_line=True, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=270, start_offset=270, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=2, argval=2, argrepr='', offset=274, start_offset=274, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=282, start_offset=282, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=284, start_offset=284, starts_line=True, line_number=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=294, start_offset=294, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to 326', offset=320, start_offset=320, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, is_jump_target=False, positions=None), - Instruction(opname='CHECK_EXC_MATCH', opcode=7, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to 392', offset=358, start_offset=358, starts_line=False, line_number=22, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=402, start_offset=402, starts_line=True, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=83, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=412, start_offset=412, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, label=2, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), + Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, label=4, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=102, start_offset=102, starts_line=False, line_number=10, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None), + Instruction(opname='LOAD_FAST_CHECK', opcode=87, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, label=5, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to 206', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, label=6, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=True, line_number=13, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=1, argrepr='1', offset=150, start_offset=150, starts_line=False, line_number=13, label=None, positions=None), + Instruction(opname='BINARY_OP', opcode=45, arg=23, argval=23, argrepr='-=', offset=152, start_offset=152, starts_line=False, line_number=13, label=None, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=False, line_number=13, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, label=7, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, label=8, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, label=9, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=19, label=None, positions=None), + Instruction(opname='NOP', opcode=30, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=True, line_number=20, label=10, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=1, argrepr='1', offset=230, start_offset=230, starts_line=True, line_number=21, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=7, argval=0, argrepr='0', offset=232, start_offset=232, starts_line=False, line_number=21, label=None, positions=None), + Instruction(opname='BINARY_OP', opcode=45, arg=11, argval=11, argrepr='/', offset=234, start_offset=234, starts_line=False, line_number=21, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, label=None, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=240, start_offset=240, starts_line=True, line_number=25, label=None, positions=None), + Instruction(opname='BEFORE_WITH', opcode=2, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=1, argval='dodgy', argrepr='dodgy', offset=244, start_offset=244, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=246, start_offset=246, starts_line=True, line_number=26, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=256, start_offset=256, starts_line=False, line_number=26, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=258, start_offset=258, starts_line=False, line_number=26, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=26, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=268, start_offset=268, starts_line=True, line_number=25, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=270, start_offset=270, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=2, argval=2, argrepr='', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=282, start_offset=282, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=284, start_offset=284, starts_line=True, line_number=28, label=11, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=294, start_offset=294, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, label=None, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to 326', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, label=12, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, label=None, positions=None), + Instruction(opname='CHECK_EXC_MATCH', opcode=7, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to 392', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, label=13, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=402, start_offset=402, starts_line=True, line_number=28, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=412, start_offset=412, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, label=None, positions=None), ] # One last piece of inspect fodder to check the default line number handling def simple(): pass expected_opinfo_simple = [ - Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, is_jump_target=False, positions=None), - Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, is_jump_target=False), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, positions=None), + Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), ] @@ -1951,7 +1951,7 @@ def roots(a, b, c): def test_oparg_alias(self): instruction = Instruction(opname="NOP", opcode=dis.opmap["NOP"], arg=None, argval=None, - argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, positions=None) self.assertEqual(instruction.arg, instruction.oparg) @@ -1959,7 +1959,7 @@ def test_baseopname_and_baseopcode(self): # Standard instructions for name, code in dis.opmap.items(): instruction = Instruction(opname=name, opcode=code, arg=None, argval=None, argrepr='', offset=0, - start_offset=0, starts_line=True, line_number=1, is_jump_target=False, positions=None) + start_offset=0, starts_line=True, line_number=1, label=None, positions=None) baseopname = instruction.baseopname baseopcode = instruction.baseopcode self.assertIsNotNone(baseopname) @@ -1970,7 +1970,7 @@ def test_baseopname_and_baseopcode(self): # Specialized instructions for name in opcode._specialized_opmap: instruction = Instruction(opname=name, opcode=dis._all_opmap[name], arg=None, argval=None, argrepr='', - offset=0, start_offset=0, starts_line=True, line_number=1, is_jump_target=False, positions=None) + offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None) baseopname = instruction.baseopname baseopcode = instruction.baseopcode self.assertIn(name, opcode._specializations[baseopname]) @@ -1979,25 +1979,25 @@ def test_baseopname_and_baseopcode(self): def test_jump_target(self): # Non-jump instructions should return None instruction = Instruction(opname="NOP", opcode=dis.opmap["NOP"], arg=None, argval=None, - argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, positions=None) self.assertIsNone(instruction.jump_target) delta = 100 instruction = Instruction(opname="JUMP_FORWARD", opcode=dis.opmap["JUMP_FORWARD"], arg=delta, argval=delta, - argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, positions=None) self.assertEqual(10 + 2 + 100*2, instruction.jump_target) # Test negative deltas instruction = Instruction(opname="JUMP_BACKWARD", opcode=dis.opmap["JUMP_BACKWARD"], arg=delta, argval=delta, - argrepr='', offset=200, start_offset=200, starts_line=True, line_number=1, is_jump_target=False, + argrepr='', offset=200, start_offset=200, starts_line=True, line_number=1, label=None, positions=None) self.assertEqual(200 + 2 - 100*2 + 2*1, instruction.jump_target) # Make sure cache entries are handled instruction = Instruction(opname="SEND", opcode=dis.opmap["SEND"], arg=delta, argval=delta, - argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, positions=None) self.assertEqual(10 + 2 + 1*2 + 100*2, instruction.jump_target) From 54cb8ca3dff4e6b3f465a5b31e3429cc9e8babb2 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 16 Nov 2023 01:03:57 +0000 Subject: [PATCH 02/24] replace offsets by labels --- Lib/dis.py | 47 +- Lib/test/test_dis.py | 1033 ++++++++++++++++++++---------------------- 2 files changed, 520 insertions(+), 560 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index d934caf5066870..377480627a50d9 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -311,6 +311,15 @@ def _get_jump_target(op, arg, offset): target = None return target +def _label_string(label, width=None, suffix=''): + if label is not None: + lbl = f'{label}' + padding = width - len(lbl) if width is not None else 0 + assert padding >= 0 + return f"L{lbl}{suffix}{'':<{padding}}" + else: + return ' ' * (width + 1 + len(suffix)) + class Instruction(_Instruction): """Details for a bytecode operation. @@ -331,7 +340,8 @@ class Instruction(_Instruction): """ @staticmethod - def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg): + def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg, + labels_map, label_width): get_name = None if names is None else names.__getitem__ argval = None argrepr = '' @@ -361,13 +371,13 @@ def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg): argval, argrepr = _get_name_info(arg, get_name) elif deop in hasjabs: argval = arg*2 - argrepr = "to " + repr(argval) + argrepr = f"to {_label_string(labels_map[argval])}" elif deop in hasjrel: signed_arg = -arg if _is_backward_jump(deop) else arg argval = offset + 2 + signed_arg*2 caches = _get_cache_size(_all_opname[deop]) argval += 2 * caches - argrepr = "to " + repr(argval) + argrepr = f"to {_label_string(labels_map[argval])}" elif deop in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST): arg1 = arg >> 4 arg2 = arg & 15 @@ -399,14 +409,21 @@ def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg): @classmethod def _create(cls, op, arg, offset, start_offset, starts_line, line_number, - label, positions, - co_consts=None, varname_from_oparg=None, names=None): + positions, + co_consts=None, varname_from_oparg=None, names=None, + labels_map=None): + + label_width = len(str(len(labels_map))) argval, argrepr = cls._get_argval_argrepr( op, arg, offset, - co_consts, names, varname_from_oparg) - return Instruction(_all_opname[op], op, arg, argval, argrepr, - offset, start_offset, starts_line, line_number, - label, positions) + co_consts, names, varname_from_oparg, labels_map, + label_width) + label = labels_map.get(offset, None) + instr = Instruction(_all_opname[op], op, arg, argval, argrepr, + offset, start_offset, starts_line, line_number, + label, positions) + instr.label_width = label_width + return instr @property def oparg(self): @@ -474,12 +491,7 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): else: fields.append(' ') # Column: Jump target marker - if self.is_jump_target: - fields.append('>>') - else: - fields.append(' ') - # Column: Instruction offset from start of code sequence - fields.append(repr(self.offset).rjust(offset_width)) + fields.append(_label_string(self.label, width=self.label_width, suffix=': ')) # Column: Opcode name fields.append(self.opname.ljust(_OPNAME_WIDTH)) # Column: Opcode argument @@ -637,8 +649,9 @@ def make_labels_map(original_code, exception_entries): op = code[offset] yield Instruction._create(op, arg, offset, start_offset, starts_line, line_number, - labels_map.get(offset, None), positions, co_consts=co_consts, - varname_from_oparg=varname_from_oparg, names=names) + positions, co_consts=co_consts, + varname_from_oparg=varname_from_oparg, names=names, + labels_map=labels_map) caches = _get_cache_size(_all_opname[deop]) if not caches: diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 34c6ab5891a5ae..e9479c786bf7b8 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -42,45 +42,45 @@ def cm(cls, x): cls.x = x == 1 dis_c_instance_method = """\ -%3d RESUME 0 - -%3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (self) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (self) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ - RESUME 0 - LOAD_FAST 1 - LOAD_CONST 1 - COMPARE_OP 72 (==) - LOAD_FAST 0 - STORE_ATTR 0 - RETURN_CONST 0 + RESUME 0 + LOAD_FAST 1 + LOAD_CONST 1 + COMPARE_OP 72 (==) + LOAD_FAST 0 + STORE_ATTR 0 + RETURN_CONST 0 """ dis_c_class_method = """\ -%3d RESUME 0 - -%3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (cls) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (cls) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - STORE_FAST 0 (x) - RETURN_CONST 0 (None) +%3d LOAD_FAST 0 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + STORE_FAST 0 (x) + RETURN_CONST 0 (None) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -100,26 +100,26 @@ def _f(a): return 1 dis_f = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_GLOBAL 1 (print + NULL) - LOAD_FAST 0 (a) - CALL 1 - POP_TOP +%3d LOAD_GLOBAL 1 (print + NULL) + LOAD_FAST 0 (a) + CALL 1 + POP_TOP -%3d RETURN_CONST 1 (1) +%3d RETURN_CONST 1 (1) """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) dis_f_co_code = """\ - RESUME 0 - LOAD_GLOBAL 1 - LOAD_FAST 0 - CALL 1 - POP_TOP - RETURN_CONST 1 + RESUME 0 + LOAD_GLOBAL 1 + LOAD_FAST 0 + CALL 1 + POP_TOP + RETURN_CONST 1 """ @@ -129,22 +129,22 @@ def bug708901(): pass dis_bug708901 = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) +%3d LOAD_GLOBAL 1 (range + NULL) + LOAD_CONST 1 (1) -%3d LOAD_CONST 2 (10) +%3d LOAD_CONST 2 (10) -%3d CALL 2 - GET_ITER - >> FOR_ITER 3 (to 36) - STORE_FAST 0 (res) +%3d CALL 2 + GET_ITER + L1: FOR_ITER 3 (to L2) + STORE_FAST 0 (res) -%3d JUMP_BACKWARD 5 (to 26) +%3d JUMP_BACKWARD 5 (to L1) -%3d >> END_FOR - RETURN_CONST 0 (None) +%3d L2: END_FOR + RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -159,20 +159,20 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_ASSERTION_ERROR - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - LOAD_FAST 0 (x) - GET_ITER - CALL 0 +%3d LOAD_ASSERTION_ERROR + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + LOAD_FAST 0 (x) + GET_ITER + CALL 0 -%3d LOAD_CONST 2 (1) +%3d LOAD_CONST 2 (1) -%3d BINARY_OP 0 (+) - CALL 0 - RAISE_VARARGS 1 +%3d BINARY_OP 0 (+) + CALL 0 + RAISE_VARARGS 1 """ % (bug1333982.__code__.co_firstlineno, bug1333982.__code__.co_firstlineno + 1, __file__, @@ -190,8 +190,8 @@ def bug42562(): dis_bug42562 = """\ - RESUME 0 - RETURN_CONST 0 (None) + RESUME 0 + RETURN_CONST 0 (None) """ # Extended arg followed by NOP @@ -204,11 +204,11 @@ def bug42562(): ]) dis_bug_45757 = """\ - EXTENDED_ARG 1 - NOP - EXTENDED_ARG 1 - LOAD_CONST 297 - RETURN_VALUE + EXTENDED_ARG 1 + NOP + EXTENDED_ARG 1 + LOAD_CONST 297 + RETURN_VALUE """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -221,10 +221,10 @@ def bug42562(): dis_bug46724 = """\ - >> EXTENDED_ARG 255 - EXTENDED_ARG 65535 - EXTENDED_ARG 16777215 - JUMP_FORWARD -4 (to 0) + L1: EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to L1) """ def func_w_kwargs(a, b, **c): @@ -234,96 +234,96 @@ def wrap_func_w_kwargs(): func_w_kwargs(1, 2, c=5) dis_kw_names = """\ -%3d RESUME 0 - -%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_CONST 1 (1) - LOAD_CONST 2 (2) - LOAD_CONST 3 (5) - LOAD_CONST 4 (('c',)) - CALL_KW 3 - POP_TOP - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) + LOAD_CONST 1 (1) + LOAD_CONST 2 (2) + LOAD_CONST 3 (5) + LOAD_CONST 4 (('c',)) + CALL_KW 3 + POP_TOP + RETURN_CONST 0 (None) """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) dis_intrinsic_1_2 = """\ - 0 RESUME 0 - - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) - IMPORT_NAME 0 (math) - CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) - POP_TOP - RETURN_CONST 2 (None) + 0 RESUME 0 + + 1 LOAD_CONST 0 (0) + LOAD_CONST 1 (('*',)) + IMPORT_NAME 0 (math) + CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) + POP_TOP + RETURN_CONST 2 (None) """ dis_intrinsic_1_5 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (a) - CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE + 1 LOAD_NAME 0 (a) + CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) + RETURN_VALUE """ dis_intrinsic_1_6 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 BUILD_LIST 0 - LOAD_NAME 0 (a) - LIST_EXTEND 1 - CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE + 1 BUILD_LIST 0 + LOAD_NAME 0 (a) + LIST_EXTEND 1 + CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) + RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ - 1 RESUME 0 + 1 RESUME 0 -%3d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) +%3d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ _BIG_LINENO_FORMAT2 = """\ - 1 RESUME 0 + 1 RESUME 0 -%4d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) +%4d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ dis_module_expected_results = """\ Disassembly of f: - 4 RESUME 0 - RETURN_CONST 0 (None) + 4 RESUME 0 + RETURN_CONST 0 (None) Disassembly of g: - 5 RESUME 0 - RETURN_CONST 0 (None) + 5 RESUME 0 + RETURN_CONST 0 (None) """ expr_str = "x + 1" dis_expr_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - RETURN_VALUE + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + RETURN_VALUE """ simple_stmt_str = "x = x + 1" dis_simple_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - STORE_NAME 0 (x) - RETURN_CONST 1 (None) + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + STORE_NAME 0 (x) + RETURN_CONST 1 (None) """ annot_stmt_str = """\ @@ -335,34 +335,34 @@ def wrap_func_w_kwargs(): # leading newline is for a reason (tests lineno) dis_annot_stmt_str = """\ - 0 RESUME 0 - - 2 SETUP_ANNOTATIONS - LOAD_CONST 0 (1) - STORE_NAME 0 (x) - LOAD_NAME 1 (int) - LOAD_NAME 2 (__annotations__) - LOAD_CONST 1 ('x') - STORE_SUBSCR - - 3 LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 0 (1) - CALL 1 - LOAD_NAME 2 (__annotations__) - LOAD_CONST 2 ('y') - STORE_SUBSCR - - 4 LOAD_CONST 0 (1) - LOAD_NAME 4 (lst) - LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 3 (0) - CALL 1 - STORE_SUBSCR - LOAD_NAME 1 (int) - POP_TOP - RETURN_CONST 4 (None) + 0 RESUME 0 + + 2 SETUP_ANNOTATIONS + LOAD_CONST 0 (1) + STORE_NAME 0 (x) + LOAD_NAME 1 (int) + LOAD_NAME 2 (__annotations__) + LOAD_CONST 1 ('x') + STORE_SUBSCR + + 3 LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 0 (1) + CALL 1 + LOAD_NAME 2 (__annotations__) + LOAD_CONST 2 ('y') + STORE_SUBSCR + + 4 LOAD_CONST 0 (1) + LOAD_NAME 4 (lst) + LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 3 (0) + CALL 1 + STORE_SUBSCR + LOAD_NAME 1 (int) + POP_TOP + RETURN_CONST 4 (None) """ compound_stmt_str = """\ @@ -372,62 +372,62 @@ def wrap_func_w_kwargs(): # Trailing newline has been deliberately omitted dis_compound_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_CONST 0 (0) - STORE_NAME 0 (x) + 1 LOAD_CONST 0 (0) + STORE_NAME 0 (x) - 2 NOP + 2 NOP - 3 >> LOAD_NAME 0 (x) - LOAD_CONST 1 (1) - BINARY_OP 13 (+=) - STORE_NAME 0 (x) + 3 L1: LOAD_NAME 0 (x) + LOAD_CONST 1 (1) + BINARY_OP 13 (+=) + STORE_NAME 0 (x) - 2 JUMP_BACKWARD 7 (to 8) + 2 JUMP_BACKWARD 7 (to L1) """ dis_traceback = """\ -%4d RESUME 0 +%4d RESUME 0 -%4d NOP +%4d NOP -%4d LOAD_CONST 1 (1) - LOAD_CONST 2 (0) - --> BINARY_OP 11 (/) - POP_TOP +%4d LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP -%4d LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE +%4d LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE -None >> PUSH_EXC_INFO +None L1: PUSH_EXC_INFO -%4d LOAD_GLOBAL 0 (Exception) - CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to 82) - STORE_FAST 0 (e) +%4d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to L3) + STORE_FAST 0 (e) -%4d LOAD_FAST 0 (e) - LOAD_ATTR 2 (__traceback__) - STORE_FAST 1 (tb) - POP_EXCEPT - LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) +%4d LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) + POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) -%4d LOAD_FAST 1 (tb) - RETURN_VALUE +%4d LOAD_FAST 1 (tb) + RETURN_VALUE -None >> LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - RERAISE 1 +None L2: LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 -%4d >> RERAISE 0 +%4d L3: RERAISE 0 -None >> COPY 3 - POP_EXCEPT - RERAISE 1 +None L4: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 4 rows """ % (TRACEBACK_CODE.co_firstlineno, @@ -443,25 +443,25 @@ def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' dis_fstring = """\ -%3d RESUME 0 - -%3d LOAD_FAST 0 (a) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 1 (b) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - LOAD_CONST 1 (' ') - LOAD_FAST 2 (c) - CONVERT_VALUE 2 (repr) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 3 (d) - CONVERT_VALUE 2 (repr) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - BUILD_STRING 7 - RETURN_VALUE +%3d RESUME 0 + +%3d LOAD_FAST 0 (a) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 1 (b) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + LOAD_CONST 1 (' ') + LOAD_FAST 2 (c) + CONVERT_VALUE 2 (repr) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 3 (d) + CONVERT_VALUE 2 (repr) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + BUILD_STRING 7 + RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -470,42 +470,42 @@ def _with(c): y = 2 dis_with = """\ -%4d RESUME 0 - -%4d LOAD_FAST 0 (c) - BEFORE_WITH - POP_TOP - -%4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -%4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -%4d >> PUSH_EXC_INFO - WITH_EXCEPT_START - TO_BOOL - POP_JUMP_IF_TRUE 1 (to 52) - RERAISE 2 - >> POP_TOP - POP_EXCEPT - POP_TOP - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -None >> COPY 3 - POP_EXCEPT - RERAISE 1 +%4d RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_WITH + POP_TOP + +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%4d L1: PUSH_EXC_INFO + WITH_EXCEPT_START + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L2) + RERAISE 2 + L2: POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +None L3: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 2 rows """ % (_with.__code__.co_firstlineno, @@ -523,76 +523,76 @@ async def _asyncwith(c): y = 2 dis_asyncwith = """\ -%4d RETURN_GENERATOR - POP_TOP - RESUME 0 - -%4d LOAD_FAST 0 (c) - BEFORE_ASYNC_WITH - GET_AWAITABLE 1 - LOAD_CONST 0 (None) - >> SEND 3 (to 24) - YIELD_VALUE 1 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to 14) - >> END_SEND - POP_TOP - -%4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -%4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - GET_AWAITABLE 2 - LOAD_CONST 0 (None) - >> SEND 3 (to 60) - YIELD_VALUE 1 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to 50) - >> END_SEND - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -%4d >> CLEANUP_THROW - -None JUMP_BACKWARD 26 (to 24) - -%4d >> CLEANUP_THROW - -None JUMP_BACKWARD 11 (to 60) - -%4d >> PUSH_EXC_INFO - WITH_EXCEPT_START - GET_AWAITABLE 2 - LOAD_CONST 0 (None) - >> SEND 4 (to 102) - YIELD_VALUE 1 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to 90) - >> CLEANUP_THROW - >> END_SEND - TO_BOOL - POP_JUMP_IF_TRUE 1 (to 118) - RERAISE 2 - >> POP_TOP - POP_EXCEPT - POP_TOP - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -None >> COPY 3 - POP_EXCEPT - RERAISE 1 - >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 +%4d RETURN_GENERATOR + POP_TOP + RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) + L1: SEND 3 (to L2) + YIELD_VALUE 1 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L1) + L2: END_SEND + POP_TOP + +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + L3: SEND 3 (to L4) + YIELD_VALUE 1 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L3) + L4: END_SEND + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%4d L5: CLEANUP_THROW + +None JUMP_BACKWARD 26 (to L2) + +%4d L6: CLEANUP_THROW + +None JUMP_BACKWARD 11 (to L4) + +%4d L7: PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + L8: SEND 4 (to L10) + YIELD_VALUE 1 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) + L9: CLEANUP_THROW + L10: END_SEND + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L11) + RERAISE 2 + L11: POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +None L12: COPY 3 + POP_EXCEPT + RERAISE 1 + L13: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: 12 rows """ % (_asyncwith.__code__.co_firstlineno, @@ -620,29 +620,29 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ -%4d RESUME 0 +%4d RESUME 0 -%4d NOP +%4d NOP -%4d LOAD_FAST 0 (a) +%4d LOAD_FAST 0 (a) -%4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_VALUE +%4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_VALUE -None >> PUSH_EXC_INFO +None L1: PUSH_EXC_INFO -%4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 +%4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -None >> COPY 3 - POP_EXCEPT - RERAISE 1 +None L2: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 2 rows """ % (_tryfinally.__code__.co_firstlineno, @@ -653,29 +653,29 @@ def _tryfinallyconst(b): ) dis_tryfinallyconst = """\ -%4d RESUME 0 +%4d RESUME 0 -%4d NOP +%4d NOP -%4d NOP +%4d NOP -%4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_CONST 1 (1) +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_CONST 1 (1) -None PUSH_EXC_INFO +None PUSH_EXC_INFO -%4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -None >> COPY 3 - POP_EXCEPT - RERAISE 1 +None L1: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 1 row """ % (_tryfinallyconst.__code__.co_firstlineno, @@ -702,19 +702,19 @@ def foo(x): return foo dis_nested_0 = """\ -None MAKE_CELL 0 (y) +None MAKE_CELL 0 (y) -%4d RESUME 0 +%4d RESUME 0 -%4d LOAD_FAST 0 (y) - BUILD_TUPLE 1 - LOAD_CONST 1 () - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - STORE_FAST 1 (foo) +%4d LOAD_FAST 0 (y) + BUILD_TUPLE 1 + LOAD_CONST 1 () + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + STORE_FAST 1 (foo) -%4d LOAD_FAST 1 (foo) - RETURN_VALUE +%4d LOAD_FAST 1 (foo) + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -724,22 +724,22 @@ def foo(x): dis_nested_1 = """%s Disassembly of : -None COPY_FREE_VARS 1 - MAKE_CELL 0 (x) - -%4d RESUME 0 - -%4d LOAD_GLOBAL 1 (list + NULL) - LOAD_FAST 0 (x) - BUILD_TUPLE 1 - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - LOAD_DEREF 1 (y) - GET_ITER - CALL 0 - CALL 1 - RETURN_VALUE +None COPY_FREE_VARS 1 + MAKE_CELL 0 (x) + +%4d RESUME 0 + +%4d LOAD_GLOBAL 1 (list + NULL) + LOAD_FAST 0 (x) + BUILD_TUPLE 1 + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + LOAD_DEREF 1 (y) + GET_ITER + CALL 0 + CALL 1 + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -751,26 +751,26 @@ def foo(x): dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: -None COPY_FREE_VARS 1 - -%4d RETURN_GENERATOR - POP_TOP - RESUME 0 - LOAD_FAST 0 (.0) - >> FOR_ITER 10 (to 34) - STORE_FAST 1 (z) - LOAD_DEREF 2 (x) - LOAD_FAST 1 (z) - BINARY_OP 0 (+) - YIELD_VALUE 0 - RESUME 5 - POP_TOP - JUMP_BACKWARD 12 (to 10) - >> END_FOR - RETURN_CONST 0 (None) - -None >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 +None COPY_FREE_VARS 1 + +%4d RETURN_GENERATOR + POP_TOP + RESUME 0 + LOAD_FAST 0 (.0) + L1: FOR_ITER 10 (to L2) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + YIELD_VALUE 0 + RESUME 5 + POP_TOP + JUMP_BACKWARD 12 (to L1) + L2: END_FOR + RETURN_CONST 0 (None) + +None L3: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: 1 row """ % (dis_nested_1, @@ -784,14 +784,14 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d 0 RESUME_CHECK 0 +%3d RESUME_CHECK 0 -%3d 2 LOAD_FAST_LOAD_FAST 1 (x, y) - 4 STORE_FAST_STORE_FAST 50 (b, a) +%3d LOAD_FAST_LOAD_FAST 1 (x, y) + STORE_FAST_STORE_FAST 50 (b, a) -%3d 6 LOAD_FAST_LOAD_FAST 35 (a, b) - 8 BUILD_TUPLE 2 - 10 RETURN_VALUE +%3d LOAD_FAST_LOAD_FAST 35 (a, b) + BUILD_TUPLE 2 + RETURN_VALUE """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -801,25 +801,25 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d RESUME_CHECK 0 - -%3d BUILD_LIST 0 - LOAD_CONST 1 ((1, 2, 3)) - LIST_EXTEND 1 - LOAD_CONST 2 (3) - BINARY_OP 5 (*) - GET_ITER - >> FOR_ITER_LIST 14 (to 48) - STORE_FAST 0 (i) - -%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) - LOAD_FAST 0 (i) - CALL_PY_WITH_DEFAULTS 1 - POP_TOP - JUMP_BACKWARD 16 (to 16) - -%3d >> END_FOR - RETURN_CONST 0 (None) +%3d RESUME_CHECK 0 + +%3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER + L1: FOR_ITER_LIST 14 (to L2) + STORE_FAST 0 (i) + +%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 16 (to L1) + +%3d L2: END_FOR + RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -829,14 +829,14 @@ def extended_arg_quick(): *_, _ = ... dis_extended_arg_quick_code = """\ -%3d 0 RESUME 0 - -%3d 2 LOAD_CONST 1 (Ellipsis) - 4 EXTENDED_ARG 1 - 6 UNPACK_EX 256 - 8 POP_TOP - 10 STORE_FAST 0 (_) - 12 RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_CONST 1 (Ellipsis) + EXTENDED_ARG 1 + UNPACK_EX 256 + POP_TOP + STORE_FAST 0 (_) + RETURN_CONST 0 (None) """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -866,22 +866,6 @@ def find_offset_column(self, lines): end += 1 return end-5, end - def assert_offsets_increasing(self, text, delta): - expected_offset = 0 - lines = text.splitlines() - start, end = self.find_offset_column(lines) - for line in lines: - if not line: - continue - if line.startswith("Disassembly"): - expected_offset = 0 - continue - if line.startswith("Exception"): - break - offset = int(line[start:end]) - self.assertGreaterEqual(offset, expected_offset, line) - expected_offset = offset + delta - def assert_exception_table_increasing(self, lines): prev_start, prev_end = -1, -1 count = 0 @@ -894,28 +878,22 @@ def assert_exception_table_increasing(self, lines): count += 1 return count - def strip_offsets(self, text): + def collapse_exception_table(self, text): lines = text.splitlines(True) - start, end = self.find_offset_column(lines) res = [] lines = iter(lines) for line in lines: + res.append(line) if line.startswith("Exception"): - res.append(line) break - if not line or line.startswith("Disassembly"): - res.append(line) - else: - res.append(line[:start] + line[end:]) num_rows = self.assert_exception_table_increasing(lines) if num_rows: res.append(f"{num_rows} row{'s' if num_rows > 1 else ''}\n") return "".join(res) - def do_disassembly_compare(self, got, expected, with_offsets=False): - if not with_offsets: - self.assert_offsets_increasing(got, 2) - got = self.strip_offsets(got) + def do_disassembly_compare(self, got, expected, with_exception_table=False): + if not with_exception_table: + got = self.collapse_exception_table(got) if got != expected: got = self.strip_addresses(got) self.assertEqual(got, expected) @@ -938,17 +916,16 @@ def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs): def get_disassemble_as_string(self, func, lasti=-1): return self.get_disassembly(func, lasti, False) - def do_disassembly_test(self, func, expected, with_offsets=False): + def do_disassembly_test(self, func, expected, with_exception_table=False): self.maxDiff = None got = self.get_disassembly(func, depth=0) - self.do_disassembly_compare(got, expected, with_offsets) + self.do_disassembly_compare(got, expected, with_exception_table=with_exception_table) # Add checks for dis.disco if hasattr(func, '__code__'): got_disco = io.StringIO() with contextlib.redirect_stdout(got_disco): dis.disco(func.__code__) - self.do_disassembly_compare(got_disco.getvalue(), expected, - with_offsets) + self.do_disassembly_compare(got_disco.getvalue(), expected) def test_opmap(self): self.assertEqual(dis.opmap["CACHE"], 0) @@ -1036,41 +1013,6 @@ def func(count): from test import dis_module self.do_disassembly_test(dis_module, dis_module_expected_results) - def test_big_offsets(self): - self.maxDiff = None - def func(count): - namespace = {} - func = "def foo(x):\n " + ";".join(["x = x + 1"] * count) + "\n return x" - exec(func, namespace) - return namespace['foo'] - - def expected(count, w): - s = ['''\ - 1 %*d RESUME 0 - - 2 %*d LOAD_FAST 0 (x) - %*d LOAD_CONST 1 (1) - %*d BINARY_OP 0 (+) -''' % (w, 0, w, 2, w, 4, w, 6)] - s += ['''\ - %*d STORE_FAST_LOAD_FAST 0 (x, x) - %*d LOAD_CONST 1 (1) - %*d BINARY_OP 0 (+) -''' % (w, 8*i + 10, w, 8*i + 12, w, 8*i + 14) - for i in range(count-1)] - s += ['''\ - %*d STORE_FAST 0 (x) - - 3 %*d LOAD_FAST 0 (x) - %*d RETURN_VALUE -''' % (w, 8*count + 2, w, 8*count + 4, w, 8*count + 6)] - return ''.join(s) - - for i in range(1, 5): - self.do_disassembly_test(func(i), expected(i, 4), True) - self.do_disassembly_test(func(1200), expected(1200, 4), True) - self.do_disassembly_test(func(1300), expected(1300, 5), True) - def test_disassemble_str(self): self.do_disassembly_test(expr_str, dis_expr_str) self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str) @@ -1160,7 +1102,7 @@ def test_disassemble_recursive(self): def check(expected, **kwargs): dis = self.get_disassembly(_h, **kwargs) dis = self.strip_addresses(dis) - dis = self.strip_offsets(dis) + dis = self.collapse_exception_table(dis) self.assertEqual(dis, expected) check(dis_nested_0, depth=0) @@ -1193,50 +1135,50 @@ def test_super_instructions(self): @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 2 LOAD_NAME 0 (a) - 4 LOAD_NAME 1 (b) - 6 %s - 10 RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_NAME 1 (b) + %s + RETURN_VALUE """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) got = self.get_disassembly(co_int, adaptive=True) - self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)", True) + self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)") co_unicode = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'})) got = self.get_disassembly(co_unicode, adaptive=True) - self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True) + self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)") binary_subscr_quicken = """\ - 0 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 2 LOAD_NAME 0 (a) - 4 LOAD_CONST 0 (0) - 6 %s - 10 RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_CONST 0 (0) + %s + RETURN_VALUE """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) got = self.get_disassembly(co_list, adaptive=True) - self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_LIST_INT", True) + self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_LIST_INT") co_dict = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_dict, {}, {'a': {0: '1'}})) got = self.get_disassembly(co_dict, adaptive=True) - self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT", True) + self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT") @cpython_only @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 2 LOAD_CONST 0 ('a') - 4 LOAD_ATTR_SLOT 0 (__class__) - 24 RETURN_VALUE + 1 LOAD_CONST 0 ('a') + LOAD_ATTR_SLOT 0 (__class__) + RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1247,13 +1189,13 @@ def test_load_attr_specialize(self): @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (str) - PUSH_NULL - LOAD_CONST 0 (1) - CALL_STR_1 1 - RETURN_VALUE + 1 LOAD_NAME 0 (str) + PUSH_NULL + LOAD_CONST 0 (1) + CALL_STR_1 1 + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1328,14 +1270,16 @@ def f(): op_offset = inst.offset - 2 cache_offset = inst.offset break + else: + opname = inst.opname 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 --> exists and points to the correct op + self.assertRegex(assem_op, fr"--> {opname}") # Make sure when lasti points to cache, it shows the same disassembly self.assertEqual(assem_op, assem_cache) @@ -1710,7 +1654,7 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None), - Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), + Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None), @@ -1719,15 +1663,15 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to L1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, label=2, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to L1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to L5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, label=4, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, label=None, positions=None), @@ -1735,7 +1679,7 @@ def _prepare_test_cases(): Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None), Instruction(opname='LOAD_FAST_CHECK', opcode=87, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, label=5, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to 206', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to L9', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, label=6, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None), @@ -1747,17 +1691,17 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to L7', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to L5', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, label=7, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to L8', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to L10', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, label=8, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to L9', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to L6', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, label=9, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None), @@ -1787,27 +1731,27 @@ def _prepare_test_cases(): Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, label=None, positions=None), Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to 326', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to L12', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, label=12, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to L11', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, label=None, positions=None), Instruction(opname='CHECK_EXC_MATCH', opcode=7, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to 392', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to L13', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to L11', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, label=13, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, label=None, positions=None), @@ -2002,7 +1946,9 @@ def test_jump_target(self): self.assertEqual(10 + 2 + 1*2 + 100*2, instruction.jump_target) def test_argval_argrepr(self): - f = dis.Instruction._get_argval_argrepr + def f(*args): + return dis.Instruction._get_argval_argrepr( + *args, labels_map={24: 1}, label_width=1) offset = 42 co_consts = (0, 1, 2, 3) @@ -2012,7 +1958,7 @@ def test_argval_argrepr(self): self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, '')) self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1')) self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 2, *args), ('a', 'a')) - self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to 24')) + self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1')) self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<')) self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults')) self.assertEqual(f(opcode.opmap["BINARY_OP"], 3, *args), (3, '<<')) @@ -2149,7 +2095,8 @@ def test_from_traceback_dis(self): self.maxDiff = None tb = get_tb() b = dis.Bytecode.from_traceback(tb) - self.assertEqual(self.strip_offsets(b.dis()), dis_traceback) + got = self.collapse_exception_table(b.dis()) + self.assertEqual(got, dis_traceback) @requires_debug_ranges() def test_bytecode_co_positions(self): From c363ee84fa7a412287df04b72de65eab5fe3ccb9 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:18:15 +0000 Subject: [PATCH 03/24] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst diff --git a/Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst b/Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst new file mode 100644 index 00000000000000..6b61d051966846 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst @@ -0,0 +1 @@ +Change :mod:`dis` output to display logical labels for jump targets instead of offsets. From 852c5c4cbf588cea13d792072aa0ce4c64e70d98 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 16 Nov 2023 19:22:21 +0000 Subject: [PATCH 04/24] distinguish between jump targets (J) and exception handlers (H) --- Doc/whatsnew/3.13.rst | 7 +++ Lib/dis.py | 34 +++++++---- Lib/test/test_dis.py | 130 +++++++++++++++++++++--------------------- 3 files changed, 96 insertions(+), 75 deletions(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index b64cfc51f75701..ef5bdf6b845797 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -168,6 +168,13 @@ copy any user classes which define the :meth:`!__replace__` method. (Contributed by Serhiy Storchaka in :gh:`108751`.) +dis +--- + +* Change the output of :mod:`dis` module functions to show logical + labels for jump targets and exception handlers, rather than offsets. + (Contributed by Irit Katriel in :gh:`112137`.) + dbm --- diff --git a/Lib/dis.py b/Lib/dis.py index 377480627a50d9..b8fdba949f2571 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -284,9 +284,12 @@ def show_code(co, *, file=None): _Instruction.label.__doc__ = "A label (int > 0) if this instruction is a jump target, otherwise None" _Instruction.positions.__doc__ = "dis.Positions object holding the span of source code covered by this instruction" -_ExceptionTableEntry = collections.namedtuple("_ExceptionTableEntry", +_ExceptionTableEntryBase = collections.namedtuple("_ExceptionTableEntryBase", "start end target depth lasti") +class _ExceptionTableEntry(_ExceptionTableEntryBase): + pass + _OPNAME_WIDTH = 20 _OPARG_WIDTH = 5 @@ -311,12 +314,13 @@ def _get_jump_target(op, arg, offset): target = None return target -def _label_string(label, width=None, suffix=''): - if label is not None: +def _label_string(label_info, width=None, suffix=''): + if label_info is not None: + label, prefix = label_info lbl = f'{label}' padding = width - len(lbl) if width is not None else 0 assert padding >= 0 - return f"L{lbl}{suffix}{'':<{padding}}" + return f"{prefix}{lbl}{suffix}{'':<{padding}}" else: return ' ' * (width + 1 + len(suffix)) @@ -334,7 +338,7 @@ class Instruction(_Instruction): otherwise equal to Instruction.offset starts_line - True if this opcode starts a source line, otherwise False line_number - source line number associated with this opcode (if any), otherwise None - label - A label (int > 0) if this instruction is a jump target, otherwise None + label - A label if this instruction is a jump target, otherwise None positions - Optional dis.Positions object holding the span of source code covered by this instruction """ @@ -421,7 +425,8 @@ def _create(cls, op, arg, offset, start_offset, starts_line, line_number, label = labels_map.get(offset, None) instr = Instruction(_all_opname[op], op, arg, argval, argrepr, offset, start_offset, starts_line, line_number, - label, positions) + label[0] if label else None, positions) + instr.label_info = label instr.label_width = label_width return instr @@ -491,7 +496,9 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): else: fields.append(' ') # Column: Jump target marker - fields.append(_label_string(self.label, width=self.label_width, suffix=': ')) + fields.append(_label_string(self.label_info, + width=self.label_width, + suffix=': ')) # Column: Opcode name fields.append(self.opname.ljust(_OPNAME_WIDTH)) # Column: Opcode argument @@ -624,11 +631,17 @@ def _get_instructions_bytes(code, varname_from_oparg=None, get_name = None if names is None else names.__getitem__ def make_labels_map(original_code, exception_entries): - labels = set(findlabels(original_code)) + jump_targets = set(findlabels(original_code)) + labels = set(jump_targets) for start, end, target, _, _ in exception_entries: for i in range(start, end): labels.add(target) - return {offset: i+1 for (i, offset) in enumerate(sorted(labels))} + labels = sorted(labels) + labels_map = {offset: (i+1, 'J' if offset in jump_targets else 'H') + for (i, offset) in enumerate(sorted(labels))} + for e in exception_entries: + e.target_label = labels_map[e.target][0] + return labels_map labels_map = make_labels_map(original_code, exception_entries) @@ -752,7 +765,8 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, for entry in exception_entries: lasti = " lasti" if entry.lasti else "" end = entry.end-2 - print(f" {entry.start} to {end} -> {entry.target} [{entry.depth}]{lasti}", file=file) + target_lbl = entry.target_label + print(f" {entry.start} to {end} -> H{target_lbl} [{entry.depth}]{lasti}", file=file) def _disassemble_str(source, **kwargs): """Compile the source string, then disassemble the code object.""" diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index e9479c786bf7b8..f5b0871c3dd2f5 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -138,12 +138,12 @@ def bug708901(): %3d CALL 2 GET_ITER - L1: FOR_ITER 3 (to L2) + J1: FOR_ITER 3 (to J2) STORE_FAST 0 (res) -%3d JUMP_BACKWARD 5 (to L1) +%3d JUMP_BACKWARD 5 (to J1) -%3d L2: END_FOR +%3d J2: END_FOR RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, @@ -221,10 +221,10 @@ def bug42562(): dis_bug46724 = """\ - L1: EXTENDED_ARG 255 + J1: EXTENDED_ARG 255 EXTENDED_ARG 65535 EXTENDED_ARG 16777215 - JUMP_FORWARD -4 (to L1) + JUMP_FORWARD -4 (to J1) """ def func_w_kwargs(a, b, **c): @@ -379,12 +379,12 @@ def wrap_func_w_kwargs(): 2 NOP - 3 L1: LOAD_NAME 0 (x) + 3 J1: LOAD_NAME 0 (x) LOAD_CONST 1 (1) BINARY_OP 13 (+=) STORE_NAME 0 (x) - 2 JUMP_BACKWARD 7 (to L1) + 2 JUMP_BACKWARD 7 (to J1) """ dis_traceback = """\ @@ -400,11 +400,11 @@ def wrap_func_w_kwargs(): %4d LOAD_FAST_CHECK 1 (tb) RETURN_VALUE -None L1: PUSH_EXC_INFO +None H1: PUSH_EXC_INFO %4d LOAD_GLOBAL 0 (Exception) CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to L3) + POP_JUMP_IF_FALSE 23 (to J3) STORE_FAST 0 (e) %4d LOAD_FAST 0 (e) @@ -418,14 +418,14 @@ def wrap_func_w_kwargs(): %4d LOAD_FAST 1 (tb) RETURN_VALUE -None L2: LOAD_CONST 0 (None) +None H2: LOAD_CONST 0 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) RERAISE 1 -%4d L3: RERAISE 0 +%4d J3: RERAISE 0 -None L4: COPY 3 +None H4: COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: @@ -489,12 +489,12 @@ def _with(c): STORE_FAST 2 (y) RETURN_CONST 0 (None) -%4d L1: PUSH_EXC_INFO +%4d H1: PUSH_EXC_INFO WITH_EXCEPT_START TO_BOOL - POP_JUMP_IF_TRUE 1 (to L2) + POP_JUMP_IF_TRUE 1 (to J2) RERAISE 2 - L2: POP_TOP + J2: POP_TOP POP_EXCEPT POP_TOP POP_TOP @@ -503,7 +503,7 @@ def _with(c): STORE_FAST 2 (y) RETURN_CONST 0 (None) -None L3: COPY 3 +None H3: COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: @@ -531,11 +531,11 @@ async def _asyncwith(c): BEFORE_ASYNC_WITH GET_AWAITABLE 1 LOAD_CONST 0 (None) - L1: SEND 3 (to L2) + J1: SEND 3 (to J2) YIELD_VALUE 1 RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L1) - L2: END_SEND + JUMP_BACKWARD_NO_INTERRUPT 5 (to J1) + J2: END_SEND POP_TOP %4d LOAD_CONST 1 (1) @@ -547,39 +547,39 @@ async def _asyncwith(c): CALL 2 GET_AWAITABLE 2 LOAD_CONST 0 (None) - L3: SEND 3 (to L4) + J3: SEND 3 (to J4) YIELD_VALUE 1 RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L3) - L4: END_SEND + JUMP_BACKWARD_NO_INTERRUPT 5 (to J3) + J4: END_SEND POP_TOP %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) RETURN_CONST 0 (None) -%4d L5: CLEANUP_THROW +%4d H5: CLEANUP_THROW -None JUMP_BACKWARD 26 (to L2) +None JUMP_BACKWARD 26 (to J2) -%4d L6: CLEANUP_THROW +%4d H6: CLEANUP_THROW -None JUMP_BACKWARD 11 (to L4) +None JUMP_BACKWARD 11 (to J4) -%4d L7: PUSH_EXC_INFO +%4d H7: PUSH_EXC_INFO WITH_EXCEPT_START GET_AWAITABLE 2 LOAD_CONST 0 (None) - L8: SEND 4 (to L10) + J8: SEND 4 (to J10) YIELD_VALUE 1 RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) - L9: CLEANUP_THROW - L10: END_SEND + JUMP_BACKWARD_NO_INTERRUPT 5 (to J8) + H9: CLEANUP_THROW + J10: END_SEND TO_BOOL - POP_JUMP_IF_TRUE 1 (to L11) + POP_JUMP_IF_TRUE 1 (to J11) RERAISE 2 - L11: POP_TOP + J11: POP_TOP POP_EXCEPT POP_TOP POP_TOP @@ -588,10 +588,10 @@ async def _asyncwith(c): STORE_FAST 2 (y) RETURN_CONST 0 (None) -None L12: COPY 3 +None H12: COPY 3 POP_EXCEPT RERAISE 1 - L13: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + H13: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 ExceptionTable: 12 rows @@ -632,7 +632,7 @@ def _tryfinallyconst(b): POP_TOP RETURN_VALUE -None L1: PUSH_EXC_INFO +None H1: PUSH_EXC_INFO %4d LOAD_FAST 1 (b) PUSH_NULL @@ -640,7 +640,7 @@ def _tryfinallyconst(b): POP_TOP RERAISE 0 -None L2: COPY 3 +None H2: COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: @@ -673,7 +673,7 @@ def _tryfinallyconst(b): POP_TOP RERAISE 0 -None L1: COPY 3 +None H1: COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: @@ -757,7 +757,7 @@ def foo(x): POP_TOP RESUME 0 LOAD_FAST 0 (.0) - L1: FOR_ITER 10 (to L2) + J1: FOR_ITER 10 (to J2) STORE_FAST 1 (z) LOAD_DEREF 2 (x) LOAD_FAST 1 (z) @@ -765,11 +765,11 @@ def foo(x): YIELD_VALUE 0 RESUME 5 POP_TOP - JUMP_BACKWARD 12 (to L1) - L2: END_FOR + JUMP_BACKWARD 12 (to J1) + J2: END_FOR RETURN_CONST 0 (None) -None L3: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) +None H3: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 ExceptionTable: 1 row @@ -809,16 +809,16 @@ def loop_test(): LOAD_CONST 2 (3) BINARY_OP 5 (*) GET_ITER - L1: FOR_ITER_LIST 14 (to L2) + J1: FOR_ITER_LIST 14 (to J2) STORE_FAST 0 (i) %3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) LOAD_FAST 0 (i) CALL_PY_WITH_DEFAULTS 1 POP_TOP - JUMP_BACKWARD 16 (to L1) + JUMP_BACKWARD 16 (to J1) -%3d L2: END_FOR +%3d J2: END_FOR RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, @@ -870,7 +870,7 @@ def assert_exception_table_increasing(self, lines): prev_start, prev_end = -1, -1 count = 0 for line in lines: - m = re.match(r' (\d+) to (\d+) -> \d+ \[\d+\]', line) + m = re.match(r' (\d+) to (\d+) -> H\d+ \[\d+\]', line) start, end = [int(g) for g in m.groups()] self.assertGreaterEqual(end, start) self.assertGreater(start, prev_end) @@ -1654,7 +1654,7 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None), - Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), + Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to J4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None), @@ -1663,15 +1663,15 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to L1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to J2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to J1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, label=2, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to L1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to J3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to J1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to L5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to J5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, label=4, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, label=None, positions=None), @@ -1679,7 +1679,7 @@ def _prepare_test_cases(): Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None), Instruction(opname='LOAD_FAST_CHECK', opcode=87, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, label=5, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to L9', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to J9', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, label=6, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None), @@ -1691,17 +1691,17 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to L7', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to L5', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to J7', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to J5', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, label=7, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to L8', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to L10', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to J8', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to J10', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, label=8, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to L9', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to L6', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to J9', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to J6', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, label=9, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None), @@ -1731,27 +1731,27 @@ def _prepare_test_cases(): Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, label=None, positions=None), Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to L12', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to J12', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, label=12, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to L11', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to J11', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, label=None, positions=None), Instruction(opname='CHECK_EXC_MATCH', opcode=7, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to L13', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to J13', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to L11', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to J11', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, label=13, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, label=None, positions=None), @@ -1948,7 +1948,7 @@ def test_jump_target(self): def test_argval_argrepr(self): def f(*args): return dis.Instruction._get_argval_argrepr( - *args, labels_map={24: 1}, label_width=1) + *args, labels_map={24: (1, 'J')}, label_width=1) offset = 42 co_consts = (0, 1, 2, 3) @@ -1958,7 +1958,7 @@ def f(*args): self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, '')) self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1')) self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 2, *args), ('a', 'a')) - self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1')) + self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to J1')) self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<')) self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults')) self.assertEqual(f(opcode.opmap["BINARY_OP"], 3, *args), (3, '<<')) From af97cee3fefdb500d14ad38dd3aa724cf692c2e6 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 16 Nov 2023 22:03:11 +0000 Subject: [PATCH 05/24] nice exception ranges --- Lib/dis.py | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index b8fdba949f2571..882727a68d6a11 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -415,7 +415,7 @@ def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg, def _create(cls, op, arg, offset, start_offset, starts_line, line_number, positions, co_consts=None, varname_from_oparg=None, names=None, - labels_map=None): + labels_map=None, exceptions_map=None): label_width = len(str(len(labels_map))) argval, argrepr = cls._get_argval_argrepr( @@ -428,6 +428,7 @@ def _create(cls, op, arg, offset, start_offset, starts_line, line_number, label[0] if label else None, positions) instr.label_info = label instr.label_width = label_width + instr.exc_handler = exceptions_map.get(offset, None) return instr @property @@ -482,6 +483,8 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): *offset_width* sets the width of the instruction offset field """ fields = [] + # Column: Exception handlers + fields.append(' ' * (self.label_width + 3)) # Column: Source code line number if lineno_width: if self.starts_line: @@ -634,8 +637,7 @@ def make_labels_map(original_code, exception_entries): jump_targets = set(findlabels(original_code)) labels = set(jump_targets) for start, end, target, _, _ in exception_entries: - for i in range(start, end): - labels.add(target) + labels.add(target) labels = sorted(labels) labels_map = {offset: (i+1, 'J' if offset in jump_targets else 'H') for (i, offset) in enumerate(sorted(labels))} @@ -645,6 +647,11 @@ def make_labels_map(original_code, exception_entries): labels_map = make_labels_map(original_code, exception_entries) + exceptions_map = {} + for start, end, target, _, _ in exception_entries: + exceptions_map[start] = labels_map[target][0] + exceptions_map[end] = -1 + starts_line = False local_line_number = None line_number = None @@ -664,7 +671,7 @@ def make_labels_map(original_code, exception_entries): yield Instruction._create(op, arg, offset, start_offset, starts_line, line_number, positions, co_consts=co_consts, varname_from_oparg=varname_from_oparg, names=names, - labels_map=labels_map) + labels_map=labels_map, exceptions_map=exceptions_map) caches = _get_cache_size(_all_opname[deop]) if not caches: @@ -740,6 +747,8 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, offset_width = len(str(maxoffset)) else: offset_width = 4 + + first_char = ' ' for instr in _get_instructions_bytes(code, varname_from_oparg, names, co_consts, linestarts, line_offset=line_offset, @@ -747,18 +756,30 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, co_positions=co_positions, show_caches=show_caches, original_code=original_code): - new_source_line = (show_lineno and - instr.starts_line and - instr.offset > 0) + new_source_line = ((show_lineno and + instr.starts_line and + instr.offset > 0) or + (instr.exc_handler is not None)) + if new_source_line: - print(file=file) + if instr.exc_handler == -1: + print('-', file=file) + first_char = ' ' + print(first_char, file=file) + elif instr.exc_handler is not None: + print(first_char, file=file) + lbl = f'H{instr.exc_handler}' + print(f'{lbl:<{instr.label_width}} ', file=file) + first_char = '|' + else: + print(first_char, file=file) if show_caches: is_current_instr = instr.offset == lasti else: # Each CACHE takes 2 bytes is_current_instr = instr.offset <= lasti \ <= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)]) - print(instr._disassemble(lineno_width, is_current_instr, offset_width), + print(first_char + instr._disassemble(lineno_width, is_current_instr, offset_width), file=file) if exception_entries: print("ExceptionTable:", file=file) From d2884ed02f3fca6ce4fa327bc8fcd789745d18c6 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 17 Nov 2023 14:42:23 +0000 Subject: [PATCH 06/24] labels in exception table, and on separate line in the code --- Lib/dis.py | 67 +++++++++++++++++++----------------------------------- 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 882727a68d6a11..9d892c006df27e 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -314,16 +314,6 @@ def _get_jump_target(op, arg, offset): target = None return target -def _label_string(label_info, width=None, suffix=''): - if label_info is not None: - label, prefix = label_info - lbl = f'{label}' - padding = width - len(lbl) if width is not None else 0 - assert padding >= 0 - return f"{prefix}{lbl}{suffix}{'':<{padding}}" - else: - return ' ' * (width + 1 + len(suffix)) - class Instruction(_Instruction): """Details for a bytecode operation. @@ -375,13 +365,13 @@ def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg, argval, argrepr = _get_name_info(arg, get_name) elif deop in hasjabs: argval = arg*2 - argrepr = f"to {_label_string(labels_map[argval])}" + argrepr = f"to L{labels_map[argval]}" elif deop in hasjrel: signed_arg = -arg if _is_backward_jump(deop) else arg argval = offset + 2 + signed_arg*2 caches = _get_cache_size(_all_opname[deop]) argval += 2 * caches - argrepr = f"to {_label_string(labels_map[argval])}" + argrepr = f"to L{labels_map[argval]}" elif deop in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST): arg1 = arg >> 4 arg2 = arg & 15 @@ -425,8 +415,7 @@ def _create(cls, op, arg, offset, start_offset, starts_line, line_number, label = labels_map.get(offset, None) instr = Instruction(_all_opname[op], op, arg, argval, argrepr, offset, start_offset, starts_line, line_number, - label[0] if label else None, positions) - instr.label_info = label + label, positions) instr.label_width = label_width instr.exc_handler = exceptions_map.get(offset, None) return instr @@ -483,8 +472,8 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): *offset_width* sets the width of the instruction offset field """ fields = [] - # Column: Exception handlers - fields.append(' ' * (self.label_width + 3)) + # Column: Labels (on separate lines) + fields.append(" ") # Column: Source code line number if lineno_width: if self.starts_line: @@ -498,10 +487,6 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): fields.append('-->') else: fields.append(' ') - # Column: Jump target marker - fields.append(_label_string(self.label_info, - width=self.label_width, - suffix=': ')) # Column: Opcode name fields.append(self.opname.ljust(_OPNAME_WIDTH)) # Column: Opcode argument @@ -637,19 +622,22 @@ def make_labels_map(original_code, exception_entries): jump_targets = set(findlabels(original_code)) labels = set(jump_targets) for start, end, target, _, _ in exception_entries: + labels.add(start) + labels.add(end) labels.add(target) labels = sorted(labels) - labels_map = {offset: (i+1, 'J' if offset in jump_targets else 'H') - for (i, offset) in enumerate(sorted(labels))} + labels_map = {offset: i+1 for (i, offset) in enumerate(sorted(labels))} for e in exception_entries: - e.target_label = labels_map[e.target][0] + e.start_label = labels_map[e.start] + e.end_label = labels_map[e.end] + e.target_label = labels_map[e.target] return labels_map labels_map = make_labels_map(original_code, exception_entries) exceptions_map = {} for start, end, target, _, _ in exception_entries: - exceptions_map[start] = labels_map[target][0] + exceptions_map[start] = labels_map[target] exceptions_map[end] = -1 starts_line = False @@ -748,7 +736,6 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, else: offset_width = 4 - first_char = ' ' for instr in _get_instructions_bytes(code, varname_from_oparg, names, co_consts, linestarts, line_offset=line_offset, @@ -756,38 +743,30 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, co_positions=co_positions, show_caches=show_caches, original_code=original_code): - new_source_line = ((show_lineno and - instr.starts_line and - instr.offset > 0) or - (instr.exc_handler is not None)) + new_source_line = (show_lineno and + instr.starts_line and + instr.offset > 0) if new_source_line: - if instr.exc_handler == -1: - print('-', file=file) - first_char = ' ' - print(first_char, file=file) - elif instr.exc_handler is not None: - print(first_char, file=file) - lbl = f'H{instr.exc_handler}' - print(f'{lbl:<{instr.label_width}} ', file=file) - first_char = '|' - else: - print(first_char, file=file) + print(file=file) if show_caches: is_current_instr = instr.offset == lasti else: # Each CACHE takes 2 bytes is_current_instr = instr.offset <= lasti \ <= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)]) - print(first_char + instr._disassemble(lineno_width, is_current_instr, offset_width), + if instr.label is not None: + print(f"L{instr.label}:") + print(instr._disassemble(lineno_width, is_current_instr, offset_width), file=file) if exception_entries: print("ExceptionTable:", file=file) for entry in exception_entries: lasti = " lasti" if entry.lasti else "" - end = entry.end-2 - target_lbl = entry.target_label - print(f" {entry.start} to {end} -> H{target_lbl} [{entry.depth}]{lasti}", file=file) + start = entry.start_label + end = entry.end_label + target = entry.target_label + print(f" L{start} to L{end} -> L{target} [{entry.depth}]{lasti}", file=file) def _disassemble_str(source, **kwargs): """Compile the source string, then disassemble the code object.""" From c527ded967deeac76bf97d6916e24629382e64e9 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 17 Nov 2023 17:40:47 +0000 Subject: [PATCH 07/24] fix tests --- Lib/dis.py | 2 +- Lib/test/test_dis.py | 1037 ++++++++++++++++++++++-------------------- 2 files changed, 538 insertions(+), 501 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 9d892c006df27e..440e7a9280ff7b 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -756,7 +756,7 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, is_current_instr = instr.offset <= lasti \ <= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)]) if instr.label is not None: - print(f"L{instr.label}:") + print(f"L{instr.label}:", file=file) print(instr._disassemble(lineno_width, is_current_instr, offset_width), file=file) if exception_entries: diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index f5b0871c3dd2f5..5eed0142eaf5e1 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -42,45 +42,45 @@ def cm(cls, x): cls.x = x == 1 dis_c_instance_method = """\ -%3d RESUME 0 - -%3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (self) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (self) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ - RESUME 0 - LOAD_FAST 1 - LOAD_CONST 1 - COMPARE_OP 72 (==) - LOAD_FAST 0 - STORE_ATTR 0 - RETURN_CONST 0 + RESUME 0 + LOAD_FAST 1 + LOAD_CONST 1 + COMPARE_OP 72 (==) + LOAD_FAST 0 + STORE_ATTR 0 + RETURN_CONST 0 """ dis_c_class_method = """\ -%3d RESUME 0 - -%3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (cls) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (cls) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ -%3d RESUME 0 + %3d RESUME 0 -%3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - STORE_FAST 0 (x) - RETURN_CONST 0 (None) + %3d LOAD_FAST 0 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + STORE_FAST 0 (x) + RETURN_CONST 0 (None) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -100,26 +100,26 @@ def _f(a): return 1 dis_f = """\ -%3d RESUME 0 + %3d RESUME 0 -%3d LOAD_GLOBAL 1 (print + NULL) - LOAD_FAST 0 (a) - CALL 1 - POP_TOP + %3d LOAD_GLOBAL 1 (print + NULL) + LOAD_FAST 0 (a) + CALL 1 + POP_TOP -%3d RETURN_CONST 1 (1) + %3d RETURN_CONST 1 (1) """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) dis_f_co_code = """\ - RESUME 0 - LOAD_GLOBAL 1 - LOAD_FAST 0 - CALL 1 - POP_TOP - RETURN_CONST 1 + RESUME 0 + LOAD_GLOBAL 1 + LOAD_FAST 0 + CALL 1 + POP_TOP + RETURN_CONST 1 """ @@ -129,22 +129,24 @@ def bug708901(): pass dis_bug708901 = """\ -%3d RESUME 0 + %3d RESUME 0 -%3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) + %3d LOAD_GLOBAL 1 (range + NULL) + LOAD_CONST 1 (1) -%3d LOAD_CONST 2 (10) + %3d LOAD_CONST 2 (10) -%3d CALL 2 - GET_ITER - J1: FOR_ITER 3 (to J2) - STORE_FAST 0 (res) + %3d CALL 2 + GET_ITER +L1: + FOR_ITER 3 (to L2) + STORE_FAST 0 (res) -%3d JUMP_BACKWARD 5 (to J1) + %3d JUMP_BACKWARD 5 (to L1) -%3d J2: END_FOR - RETURN_CONST 0 (None) +L2: + %3d END_FOR + RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -159,20 +161,20 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ -%3d RESUME 0 + %3d RESUME 0 -%3d LOAD_ASSERTION_ERROR - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - LOAD_FAST 0 (x) - GET_ITER - CALL 0 + %3d LOAD_ASSERTION_ERROR + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + LOAD_FAST 0 (x) + GET_ITER + CALL 0 -%3d LOAD_CONST 2 (1) + %3d LOAD_CONST 2 (1) -%3d BINARY_OP 0 (+) - CALL 0 - RAISE_VARARGS 1 + %3d BINARY_OP 0 (+) + CALL 0 + RAISE_VARARGS 1 """ % (bug1333982.__code__.co_firstlineno, bug1333982.__code__.co_firstlineno + 1, __file__, @@ -190,8 +192,8 @@ def bug42562(): dis_bug42562 = """\ - RESUME 0 - RETURN_CONST 0 (None) + RESUME 0 + RETURN_CONST 0 (None) """ # Extended arg followed by NOP @@ -204,11 +206,11 @@ def bug42562(): ]) dis_bug_45757 = """\ - EXTENDED_ARG 1 - NOP - EXTENDED_ARG 1 - LOAD_CONST 297 - RETURN_VALUE + EXTENDED_ARG 1 + NOP + EXTENDED_ARG 1 + LOAD_CONST 297 + RETURN_VALUE """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -221,10 +223,11 @@ def bug42562(): dis_bug46724 = """\ - J1: EXTENDED_ARG 255 - EXTENDED_ARG 65535 - EXTENDED_ARG 16777215 - JUMP_FORWARD -4 (to J1) +L1: + EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to L1) """ def func_w_kwargs(a, b, **c): @@ -234,96 +237,96 @@ def wrap_func_w_kwargs(): func_w_kwargs(1, 2, c=5) dis_kw_names = """\ -%3d RESUME 0 - -%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_CONST 1 (1) - LOAD_CONST 2 (2) - LOAD_CONST 3 (5) - LOAD_CONST 4 (('c',)) - CALL_KW 3 - POP_TOP - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) + LOAD_CONST 1 (1) + LOAD_CONST 2 (2) + LOAD_CONST 3 (5) + LOAD_CONST 4 (('c',)) + CALL_KW 3 + POP_TOP + RETURN_CONST 0 (None) """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) dis_intrinsic_1_2 = """\ - 0 RESUME 0 - - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) - IMPORT_NAME 0 (math) - CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) - POP_TOP - RETURN_CONST 2 (None) + 0 RESUME 0 + + 1 LOAD_CONST 0 (0) + LOAD_CONST 1 (('*',)) + IMPORT_NAME 0 (math) + CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) + POP_TOP + RETURN_CONST 2 (None) """ dis_intrinsic_1_5 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (a) - CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE + 1 LOAD_NAME 0 (a) + CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) + RETURN_VALUE """ dis_intrinsic_1_6 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 BUILD_LIST 0 - LOAD_NAME 0 (a) - LIST_EXTEND 1 - CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE + 1 BUILD_LIST 0 + LOAD_NAME 0 (a) + LIST_EXTEND 1 + CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) + RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ - 1 RESUME 0 + 1 RESUME 0 -%3d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) + %3d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ _BIG_LINENO_FORMAT2 = """\ - 1 RESUME 0 + 1 RESUME 0 -%4d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) + %4d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ dis_module_expected_results = """\ Disassembly of f: - 4 RESUME 0 - RETURN_CONST 0 (None) + 4 RESUME 0 + RETURN_CONST 0 (None) Disassembly of g: - 5 RESUME 0 - RETURN_CONST 0 (None) + 5 RESUME 0 + RETURN_CONST 0 (None) """ expr_str = "x + 1" dis_expr_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - RETURN_VALUE + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + RETURN_VALUE """ simple_stmt_str = "x = x + 1" dis_simple_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - STORE_NAME 0 (x) - RETURN_CONST 1 (None) + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + STORE_NAME 0 (x) + RETURN_CONST 1 (None) """ annot_stmt_str = """\ @@ -335,34 +338,34 @@ def wrap_func_w_kwargs(): # leading newline is for a reason (tests lineno) dis_annot_stmt_str = """\ - 0 RESUME 0 - - 2 SETUP_ANNOTATIONS - LOAD_CONST 0 (1) - STORE_NAME 0 (x) - LOAD_NAME 1 (int) - LOAD_NAME 2 (__annotations__) - LOAD_CONST 1 ('x') - STORE_SUBSCR - - 3 LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 0 (1) - CALL 1 - LOAD_NAME 2 (__annotations__) - LOAD_CONST 2 ('y') - STORE_SUBSCR - - 4 LOAD_CONST 0 (1) - LOAD_NAME 4 (lst) - LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 3 (0) - CALL 1 - STORE_SUBSCR - LOAD_NAME 1 (int) - POP_TOP - RETURN_CONST 4 (None) + 0 RESUME 0 + + 2 SETUP_ANNOTATIONS + LOAD_CONST 0 (1) + STORE_NAME 0 (x) + LOAD_NAME 1 (int) + LOAD_NAME 2 (__annotations__) + LOAD_CONST 1 ('x') + STORE_SUBSCR + + 3 LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 0 (1) + CALL 1 + LOAD_NAME 2 (__annotations__) + LOAD_CONST 2 ('y') + STORE_SUBSCR + + 4 LOAD_CONST 0 (1) + LOAD_NAME 4 (lst) + LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 3 (0) + CALL 1 + STORE_SUBSCR + LOAD_NAME 1 (int) + POP_TOP + RETURN_CONST 4 (None) """ compound_stmt_str = """\ @@ -372,62 +375,71 @@ def wrap_func_w_kwargs(): # Trailing newline has been deliberately omitted dis_compound_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_CONST 0 (0) - STORE_NAME 0 (x) + 1 LOAD_CONST 0 (0) + STORE_NAME 0 (x) - 2 NOP + 2 NOP - 3 J1: LOAD_NAME 0 (x) - LOAD_CONST 1 (1) - BINARY_OP 13 (+=) - STORE_NAME 0 (x) +L1: + 3 LOAD_NAME 0 (x) + LOAD_CONST 1 (1) + BINARY_OP 13 (+=) + STORE_NAME 0 (x) - 2 JUMP_BACKWARD 7 (to J1) + 2 JUMP_BACKWARD 7 (to L1) """ dis_traceback = """\ -%4d RESUME 0 - -%4d NOP - -%4d LOAD_CONST 1 (1) - LOAD_CONST 2 (0) - --> BINARY_OP 11 (/) - POP_TOP - -%4d LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE - -None H1: PUSH_EXC_INFO - -%4d LOAD_GLOBAL 0 (Exception) - CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to J3) - STORE_FAST 0 (e) - -%4d LOAD_FAST 0 (e) - LOAD_ATTR 2 (__traceback__) - STORE_FAST 1 (tb) - POP_EXCEPT - LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - -%4d LOAD_FAST 1 (tb) - RETURN_VALUE - -None H2: LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - RERAISE 1 - -%4d J3: RERAISE 0 - -None H4: COPY 3 - POP_EXCEPT - RERAISE 1 + %4d RESUME 0 + + %4d NOP + +L1: + %4d LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP + +L2: + %4d LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE + +L3: + None PUSH_EXC_INFO + + %4d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to L7) + STORE_FAST 0 (e) + +L4: + %4d LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) +L5: + POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + + %4d LOAD_FAST 1 (tb) + RETURN_VALUE + +L6: + None LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 + +L7: + %4d RERAISE 0 + +L8: + None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 4 rows """ % (TRACEBACK_CODE.co_firstlineno, @@ -443,25 +455,25 @@ def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' dis_fstring = """\ -%3d RESUME 0 - -%3d LOAD_FAST 0 (a) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 1 (b) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - LOAD_CONST 1 (' ') - LOAD_FAST 2 (c) - CONVERT_VALUE 2 (repr) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 3 (d) - CONVERT_VALUE 2 (repr) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - BUILD_STRING 7 - RETURN_VALUE + %3d RESUME 0 + + %3d LOAD_FAST 0 (a) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 1 (b) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + LOAD_CONST 1 (' ') + LOAD_FAST 2 (c) + CONVERT_VALUE 2 (repr) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 3 (d) + CONVERT_VALUE 2 (repr) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + BUILD_STRING 7 + RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -470,42 +482,48 @@ def _with(c): y = 2 dis_with = """\ -%4d RESUME 0 - -%4d LOAD_FAST 0 (c) - BEFORE_WITH - POP_TOP - -%4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -%4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -%4d H1: PUSH_EXC_INFO - WITH_EXCEPT_START - TO_BOOL - POP_JUMP_IF_TRUE 1 (to J2) - RERAISE 2 - J2: POP_TOP - POP_EXCEPT - POP_TOP - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -None H3: COPY 3 - POP_EXCEPT - RERAISE 1 + %4d RESUME 0 + + %4d LOAD_FAST 0 (c) + BEFORE_WITH +L1: + POP_TOP + + %4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +L2: + %4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L3: + %4d PUSH_EXC_INFO + WITH_EXCEPT_START + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L4) + RERAISE 2 +L4: + POP_TOP +L5: + POP_EXCEPT + POP_TOP + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L6: + None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 2 rows """ % (_with.__code__.co_firstlineno, @@ -523,76 +541,101 @@ async def _asyncwith(c): y = 2 dis_asyncwith = """\ -%4d RETURN_GENERATOR - POP_TOP - RESUME 0 - -%4d LOAD_FAST 0 (c) - BEFORE_ASYNC_WITH - GET_AWAITABLE 1 - LOAD_CONST 0 (None) - J1: SEND 3 (to J2) - YIELD_VALUE 1 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to J1) - J2: END_SEND - POP_TOP - -%4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -%4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - GET_AWAITABLE 2 - LOAD_CONST 0 (None) - J3: SEND 3 (to J4) - YIELD_VALUE 1 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to J3) - J4: END_SEND - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -%4d H5: CLEANUP_THROW - -None JUMP_BACKWARD 26 (to J2) - -%4d H6: CLEANUP_THROW - -None JUMP_BACKWARD 11 (to J4) - -%4d H7: PUSH_EXC_INFO - WITH_EXCEPT_START - GET_AWAITABLE 2 - LOAD_CONST 0 (None) - J8: SEND 4 (to J10) - YIELD_VALUE 1 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to J8) - H9: CLEANUP_THROW - J10: END_SEND - TO_BOOL - POP_JUMP_IF_TRUE 1 (to J11) - RERAISE 2 - J11: POP_TOP - POP_EXCEPT - POP_TOP - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -None H12: COPY 3 - POP_EXCEPT - RERAISE 1 - H13: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 + %4d RETURN_GENERATOR + POP_TOP +L1: + RESUME 0 + + %4d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) +L2: + SEND 3 (to L5) +L3: + YIELD_VALUE 1 +L4: + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) +L5: + END_SEND +L6: + POP_TOP + + %4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +L7: + %4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) +L8: + SEND 3 (to L11) +L9: + YIELD_VALUE 1 +L10: + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) +L11: + END_SEND + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L12: + %4d CLEANUP_THROW + +L13: + None JUMP_BACKWARD 26 (to L5) + +L14: + %4d CLEANUP_THROW + +L15: + None JUMP_BACKWARD 11 (to L11) + +L16: + %4d PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) +L17: + SEND 4 (to L21) +L18: + YIELD_VALUE 1 +L19: + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) +L20: + CLEANUP_THROW +L21: + END_SEND + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L22) + RERAISE 2 +L22: + POP_TOP +L23: + POP_EXCEPT + POP_TOP + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L24: + None COPY 3 + POP_EXCEPT + RERAISE 1 +L25: + CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: 12 rows """ % (_asyncwith.__code__.co_firstlineno, @@ -620,29 +663,33 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ -%4d RESUME 0 + %4d RESUME 0 -%4d NOP + %4d NOP -%4d LOAD_FAST 0 (a) +L1: + %4d LOAD_FAST 0 (a) -%4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_VALUE +L2: + %4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_VALUE -None H1: PUSH_EXC_INFO +L3: + None PUSH_EXC_INFO -%4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 + %4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -None H2: COPY 3 - POP_EXCEPT - RERAISE 1 +L4: + None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 2 rows """ % (_tryfinally.__code__.co_firstlineno, @@ -653,29 +700,31 @@ def _tryfinallyconst(b): ) dis_tryfinallyconst = """\ -%4d RESUME 0 + %4d RESUME 0 -%4d NOP + %4d NOP -%4d NOP + %4d NOP -%4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_CONST 1 (1) + %4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_CONST 1 (1) -None PUSH_EXC_INFO +L1: + None PUSH_EXC_INFO -%4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 + %4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -None H1: COPY 3 - POP_EXCEPT - RERAISE 1 +L2: + None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 1 row """ % (_tryfinallyconst.__code__.co_firstlineno, @@ -702,19 +751,19 @@ def foo(x): return foo dis_nested_0 = """\ -None MAKE_CELL 0 (y) + None MAKE_CELL 0 (y) -%4d RESUME 0 + %4d RESUME 0 -%4d LOAD_FAST 0 (y) - BUILD_TUPLE 1 - LOAD_CONST 1 () - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - STORE_FAST 1 (foo) + %4d LOAD_FAST 0 (y) + BUILD_TUPLE 1 + LOAD_CONST 1 () + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + STORE_FAST 1 (foo) -%4d LOAD_FAST 1 (foo) - RETURN_VALUE + %4d LOAD_FAST 1 (foo) + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -724,22 +773,22 @@ def foo(x): dis_nested_1 = """%s Disassembly of : -None COPY_FREE_VARS 1 - MAKE_CELL 0 (x) - -%4d RESUME 0 - -%4d LOAD_GLOBAL 1 (list + NULL) - LOAD_FAST 0 (x) - BUILD_TUPLE 1 - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - LOAD_DEREF 1 (y) - GET_ITER - CALL 0 - CALL 1 - RETURN_VALUE + None COPY_FREE_VARS 1 + MAKE_CELL 0 (x) + + %4d RESUME 0 + + %4d LOAD_GLOBAL 1 (list + NULL) + LOAD_FAST 0 (x) + BUILD_TUPLE 1 + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + LOAD_DEREF 1 (y) + GET_ITER + CALL 0 + CALL 1 + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -751,26 +800,30 @@ def foo(x): dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: -None COPY_FREE_VARS 1 - -%4d RETURN_GENERATOR - POP_TOP - RESUME 0 - LOAD_FAST 0 (.0) - J1: FOR_ITER 10 (to J2) - STORE_FAST 1 (z) - LOAD_DEREF 2 (x) - LOAD_FAST 1 (z) - BINARY_OP 0 (+) - YIELD_VALUE 0 - RESUME 5 - POP_TOP - JUMP_BACKWARD 12 (to J1) - J2: END_FOR - RETURN_CONST 0 (None) - -None H3: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 + None COPY_FREE_VARS 1 + + %4d RETURN_GENERATOR + POP_TOP +L1: + RESUME 0 + LOAD_FAST 0 (.0) +L2: + FOR_ITER 10 (to L3) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + YIELD_VALUE 0 + RESUME 5 + POP_TOP + JUMP_BACKWARD 12 (to L2) +L3: + END_FOR + RETURN_CONST 0 (None) + +L4: + None CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: 1 row """ % (dis_nested_1, @@ -784,14 +837,14 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d RESUME_CHECK 0 + %3d RESUME_CHECK 0 -%3d LOAD_FAST_LOAD_FAST 1 (x, y) - STORE_FAST_STORE_FAST 50 (b, a) + %3d LOAD_FAST_LOAD_FAST 1 (x, y) + STORE_FAST_STORE_FAST 50 (b, a) -%3d LOAD_FAST_LOAD_FAST 35 (a, b) - BUILD_TUPLE 2 - RETURN_VALUE + %3d LOAD_FAST_LOAD_FAST 35 (a, b) + BUILD_TUPLE 2 + RETURN_VALUE """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -801,25 +854,27 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d RESUME_CHECK 0 - -%3d BUILD_LIST 0 - LOAD_CONST 1 ((1, 2, 3)) - LIST_EXTEND 1 - LOAD_CONST 2 (3) - BINARY_OP 5 (*) - GET_ITER - J1: FOR_ITER_LIST 14 (to J2) - STORE_FAST 0 (i) - -%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) - LOAD_FAST 0 (i) - CALL_PY_WITH_DEFAULTS 1 - POP_TOP - JUMP_BACKWARD 16 (to J1) - -%3d J2: END_FOR - RETURN_CONST 0 (None) + %3d RESUME_CHECK 0 + + %3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER +L1: + FOR_ITER_LIST 14 (to L2) + STORE_FAST 0 (i) + + %3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 16 (to L1) + +L2: + %3d END_FOR + RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -829,14 +884,14 @@ def extended_arg_quick(): *_, _ = ... dis_extended_arg_quick_code = """\ -%3d RESUME 0 - -%3d LOAD_CONST 1 (Ellipsis) - EXTENDED_ARG 1 - UNPACK_EX 256 - POP_TOP - STORE_FAST 0 (_) - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_CONST 1 (Ellipsis) + EXTENDED_ARG 1 + UNPACK_EX 256 + POP_TOP + STORE_FAST 0 (_) + RETURN_CONST 0 (None) """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -848,32 +903,14 @@ class DisTestBase(unittest.TestCase): def strip_addresses(self, text): return re.sub(r'\b0x[0-9A-Fa-f]+\b', '0x...', text) - def find_offset_column(self, lines): - for line in lines: - if line and not line.startswith("Disassembly"): - break - else: - return 0, 0 - offset = 5 - while (line[offset] == " "): - offset += 1 - if (line[offset] == ">"): - offset += 2 - while (line[offset] == " "): - offset += 1 - end = offset - while line[end] in "0123456789": - end += 1 - return end-5, end - def assert_exception_table_increasing(self, lines): prev_start, prev_end = -1, -1 count = 0 for line in lines: - m = re.match(r' (\d+) to (\d+) -> H\d+ \[\d+\]', line) + m = re.match(r' L(\d+) to L(\d+) -> L\d+ \[\d+\]', line) start, end = [int(g) for g in m.groups()] self.assertGreaterEqual(end, start) - self.assertGreater(start, prev_end) + self.assertGreaterEqual(start, prev_end) prev_start, prev_end = start, end count += 1 return count @@ -1135,12 +1172,12 @@ def test_super_instructions(self): @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (a) - LOAD_NAME 1 (b) - %s - RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_NAME 1 (b) + %s + RETURN_VALUE """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) @@ -1153,12 +1190,12 @@ def test_binary_specialize(self): self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)") binary_subscr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (a) - LOAD_CONST 0 (0) - %s - RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_CONST 0 (0) + %s + RETURN_VALUE """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) @@ -1174,11 +1211,11 @@ def test_binary_specialize(self): @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_CONST 0 ('a') - LOAD_ATTR_SLOT 0 (__class__) - RETURN_VALUE + 1 LOAD_CONST 0 ('a') + LOAD_ATTR_SLOT 0 (__class__) + RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1189,13 +1226,13 @@ def test_load_attr_specialize(self): @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (str) - PUSH_NULL - LOAD_CONST 0 (1) - CALL_STR_1 1 - RETURN_VALUE + 1 LOAD_NAME 0 (str) + PUSH_NULL + LOAD_CONST 0 (1) + CALL_STR_1 1 + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1279,7 +1316,7 @@ def f(): assem_cache = self.get_disassembly(f.__code__, lasti=cache_offset, wrapper=False) # Make sure --> exists and points to the correct op - self.assertRegex(assem_op, fr"--> {opname}") + self.assertRegex(assem_op, fr"--> {opname}") # Make sure when lasti points to cache, it shows the same disassembly self.assertEqual(assem_op, assem_cache) @@ -1654,7 +1691,7 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None), - Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to J4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), + Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None), Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None), @@ -1663,15 +1700,15 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to J2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to J1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to L1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, label=2, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to J3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to J1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to L1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to J5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to L5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, label=4, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, label=None, positions=None), @@ -1679,7 +1716,7 @@ def _prepare_test_cases(): Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None), Instruction(opname='LOAD_FAST_CHECK', opcode=87, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, label=5, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to J9', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to L9', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, label=6, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None), @@ -1691,17 +1728,17 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to J7', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to J5', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to L7', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to L5', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, label=7, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, label=None, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to J8', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to J10', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to L8', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to L10', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, label=8, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to J9', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to J6', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to L9', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to L6', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, label=9, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None), @@ -1731,27 +1768,27 @@ def _prepare_test_cases(): Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, label=None, positions=None), Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to J12', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to L12', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, label=12, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to J11', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to L11', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, label=None, positions=None), Instruction(opname='CHECK_EXC_MATCH', opcode=7, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, label=None, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to J13', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to L13', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, label=None, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, label=None, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to J11', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to L11', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, label=13, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, label=None, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, label=None, positions=None), @@ -1948,7 +1985,7 @@ def test_jump_target(self): def test_argval_argrepr(self): def f(*args): return dis.Instruction._get_argval_argrepr( - *args, labels_map={24: (1, 'J')}, label_width=1) + *args, labels_map={24: 1}, label_width=1) offset = 42 co_consts = (0, 1, 2, 3) @@ -1958,7 +1995,7 @@ def f(*args): self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, '')) self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1')) self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 2, *args), ('a', 'a')) - self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to J1')) + self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1')) self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<')) self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults')) self.assertEqual(f(opcode.opmap["BINARY_OP"], 3, *args), (3, '<<')) From b3914e643967c2f3278364f4100708459e9dba2a Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 17 Nov 2023 17:52:23 +0000 Subject: [PATCH 08/24] do not collapse excaption table in tests --- Lib/test/test_dis.py | 61 ++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 5eed0142eaf5e1..26a90ac5bcda57 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -441,7 +441,10 @@ def wrap_func_w_kwargs(): POP_EXCEPT RERAISE 1 ExceptionTable: -4 rows + L1 to L2 -> L3 [0] + L3 to L4 -> L8 [1] lasti + L4 to L5 -> L6 [1] lasti + L6 to L8 -> L8 [1] lasti """ % (TRACEBACK_CODE.co_firstlineno, TRACEBACK_CODE.co_firstlineno + 1, TRACEBACK_CODE.co_firstlineno + 2, @@ -525,7 +528,8 @@ def _with(c): POP_EXCEPT RERAISE 1 ExceptionTable: -2 rows + L1 to L2 -> L3 [1] lasti + L3 to L5 -> L6 [3] lasti """ % (_with.__code__.co_firstlineno, _with.__code__.co_firstlineno + 1, _with.__code__.co_firstlineno + 2, @@ -637,7 +641,18 @@ async def _asyncwith(c): CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 ExceptionTable: -12 rows + L1 to L3 -> L25 [0] lasti + L3 to L4 -> L12 [3] + L4 to L6 -> L25 [0] lasti + L6 to L7 -> L16 [1] lasti + L7 to L9 -> L25 [0] lasti + L9 to L10 -> L14 [2] + L10 to L13 -> L25 [0] lasti + L14 to L15 -> L25 [0] lasti + L16 to L18 -> L24 [3] lasti + L18 to L19 -> L20 [6] + L19 to L23 -> L24 [3] lasti + L23 to L25 -> L25 [0] lasti """ % (_asyncwith.__code__.co_firstlineno, _asyncwith.__code__.co_firstlineno + 1, _asyncwith.__code__.co_firstlineno + 2, @@ -691,7 +706,8 @@ def _tryfinallyconst(b): POP_EXCEPT RERAISE 1 ExceptionTable: -2 rows + L1 to L2 -> L3 [0] + L3 to L4 -> L4 [1] lasti """ % (_tryfinally.__code__.co_firstlineno, _tryfinally.__code__.co_firstlineno + 1, _tryfinally.__code__.co_firstlineno + 2, @@ -726,7 +742,7 @@ def _tryfinallyconst(b): POP_EXCEPT RERAISE 1 ExceptionTable: -1 row + L1 to L2 -> L2 [1] lasti """ % (_tryfinallyconst.__code__.co_firstlineno, _tryfinallyconst.__code__.co_firstlineno + 1, _tryfinallyconst.__code__.co_firstlineno + 2, @@ -825,7 +841,7 @@ def foo(x): None CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 ExceptionTable: -1 row + L1 to L4 -> L4 [0] lasti """ % (dis_nested_1, __file__, _h.__code__.co_firstlineno + 3, @@ -915,22 +931,7 @@ def assert_exception_table_increasing(self, lines): count += 1 return count - def collapse_exception_table(self, text): - lines = text.splitlines(True) - res = [] - lines = iter(lines) - for line in lines: - res.append(line) - if line.startswith("Exception"): - break - num_rows = self.assert_exception_table_increasing(lines) - if num_rows: - res.append(f"{num_rows} row{'s' if num_rows > 1 else ''}\n") - return "".join(res) - - def do_disassembly_compare(self, got, expected, with_exception_table=False): - if not with_exception_table: - got = self.collapse_exception_table(got) + def do_disassembly_compare(self, got, expected): if got != expected: got = self.strip_addresses(got) self.assertEqual(got, expected) @@ -953,10 +954,10 @@ def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs): def get_disassemble_as_string(self, func, lasti=-1): return self.get_disassembly(func, lasti, False) - def do_disassembly_test(self, func, expected, with_exception_table=False): + def do_disassembly_test(self, func, expected): self.maxDiff = None got = self.get_disassembly(func, depth=0) - self.do_disassembly_compare(got, expected, with_exception_table=with_exception_table) + self.do_disassembly_compare(got, expected) # Add checks for dis.disco if hasattr(func, '__code__'): got_disco = io.StringIO() @@ -1130,7 +1131,7 @@ def test_dis_traceback(self): sys.last_exc = e tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti) - self.do_disassembly_test(None, tb_dis, True) + self.do_disassembly_test(None, tb_dis) def test_dis_object(self): self.assertRaises(TypeError, dis.dis, object()) @@ -1139,7 +1140,6 @@ def test_disassemble_recursive(self): def check(expected, **kwargs): dis = self.get_disassembly(_h, **kwargs) dis = self.strip_addresses(dis) - dis = self.collapse_exception_table(dis) self.assertEqual(dis, expected) check(dis_nested_0, depth=0) @@ -1166,7 +1166,7 @@ def code_quicken(f, times=ADAPTIVE_WARMUP_DELAY): def test_super_instructions(self): self.code_quicken(lambda: load_test(0, 0)) got = self.get_disassembly(load_test, adaptive=True) - self.do_disassembly_compare(got, dis_load_test_quickened_code, True) + self.do_disassembly_compare(got, dis_load_test_quickened_code) @cpython_only @requires_specialization @@ -1220,7 +1220,7 @@ def test_load_attr_specialize(self): co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) got = self.get_disassembly(co, adaptive=True) - self.do_disassembly_compare(got, load_attr_quicken, True) + self.do_disassembly_compare(got, load_attr_quicken) @cpython_only @requires_specialization @@ -1255,7 +1255,7 @@ def test_loop_quicken(self): @cpython_only def test_extended_arg_quick(self): got = self.get_disassembly(extended_arg_quick) - self.do_disassembly_compare(got, dis_extended_arg_quick_code, True) + self.do_disassembly_compare(got, dis_extended_arg_quick_code) def get_cached_values(self, quickened, adaptive): def f(): @@ -2132,8 +2132,7 @@ def test_from_traceback_dis(self): self.maxDiff = None tb = get_tb() b = dis.Bytecode.from_traceback(tb) - got = self.collapse_exception_table(b.dis()) - self.assertEqual(got, dis_traceback) + self.assertEqual(b.dis(), dis_traceback) @requires_debug_ranges() def test_bytecode_co_positions(self): From efd5906c305fdc6af7b176be5425aaf347692f70 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 17 Nov 2023 18:39:09 +0000 Subject: [PATCH 09/24] update dis.rst doctest --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index e44fa46b5d4145..d484960ff0e681 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -62,12 +62,12 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 0 RESUME 0 + 2 RESUME 0 - 3 2 LOAD_GLOBAL 1 (len + NULL) - 12 LOAD_FAST 0 (alist) - 14 CALL 1 - 22 RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + RETURN_VALUE (The "2" is a line number). From 83ae74e6b8715d56846f8ef5e40c86556ab0ccb4 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 17 Nov 2023 18:52:25 +0000 Subject: [PATCH 10/24] whitespace --- Doc/library/dis.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index d484960ff0e681..9329a0ad87eb88 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -62,7 +62,7 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 3 LOAD_GLOBAL 1 (len + NULL) LOAD_FAST 0 (alist) From bac6628b8aff2838a7fbe9d24ea9eac5086fd7d9 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:28:25 +0000 Subject: [PATCH 11/24] whitespace --- Lib/dis.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/dis.py b/Lib/dis.py index 440e7a9280ff7b..b5d191c5b71dfc 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -746,7 +746,6 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, new_source_line = (show_lineno and instr.starts_line and instr.offset > 0) - if new_source_line: print(file=file) if show_caches: From 390c7a238cc995e767c9ee7262d3e5862072bbb2 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Tue, 21 Nov 2023 01:11:14 +0000 Subject: [PATCH 12/24] add option to include offset and labels on same line as instruction --- Lib/dis.py | 73 ++-- Lib/test/test_dis.py | 961 ++++++++++++++++++++----------------------- 2 files changed, 499 insertions(+), 535 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index b5d191c5b71dfc..a0f5fa2a8d25ad 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -72,7 +72,8 @@ def _try_compile(source, name): pass return compile(source, name, 'exec') -def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): +def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False, + show_offsets=False): """Disassemble classes, methods, functions, and other compiled objects. With no argument, disassemble the last traceback. @@ -82,7 +83,8 @@ def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): in a special attribute. """ if x is None: - distb(file=file, show_caches=show_caches, adaptive=adaptive) + distb(file=file, show_caches=show_caches, adaptive=adaptive, + show_offsets=show_offsets) return # Extract functions from methods. if hasattr(x, '__func__'): @@ -103,21 +105,21 @@ def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): if isinstance(x1, _have_code): print("Disassembly of %s:" % name, file=file) try: - dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) + dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) except TypeError as msg: print("Sorry:", msg, file=file) print(file=file) elif hasattr(x, 'co_code'): # Code object - _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) + _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) elif isinstance(x, (bytes, bytearray)): # Raw bytecode - _disassemble_bytes(x, file=file, show_caches=show_caches) + _disassemble_bytes(x, file=file, show_caches=show_caches, show_offsets=show_offsets) elif isinstance(x, str): # Source code - _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) + _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__) -def distb(tb=None, *, file=None, show_caches=False, adaptive=False): +def distb(tb=None, *, file=None, show_caches=False, adaptive=False, show_offsets=False): """Disassemble a traceback (default: last traceback).""" if tb is None: try: @@ -128,7 +130,7 @@ def distb(tb=None, *, file=None, show_caches=False, adaptive=False): except AttributeError: raise RuntimeError("no last traceback to disassemble") from None while tb.tb_next: tb = tb.tb_next - disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive) + disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) # The inspect module interrogates this dictionary to build its # list of CO_* constants. It is also used by pretty_flags to @@ -464,7 +466,8 @@ def is_jump_target(self): """True if other code jumps to here, otherwise False""" return self.label is not None - def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): + def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0, + label_width=4): """Format instruction details for inclusion in disassembly output. *lineno_width* sets the width of the line number field (0 omits it) @@ -472,8 +475,13 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): *offset_width* sets the width of the instruction offset field """ fields = [] - # Column: Labels (on separate lines) - fields.append(" ") + # + # Column: Label + if self.label is not None: + lbl = f"L{self.label}:" + fields.append(f"{lbl:<{label_width}}") + else: + fields.append(' ' * label_width) # Column: Source code line number if lineno_width: if self.starts_line: @@ -487,6 +495,9 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): fields.append('-->') else: fields.append(' ') + # Column: Instruction offset from start of code sequence + if offset_width > 0: + fields.append(f"{repr(self.offset):>{offset_width}} ") # Column: Opcode name fields.append(self.opname.ljust(_OPNAME_WIDTH)) # Column: Opcode argument @@ -680,11 +691,12 @@ def make_labels_map(original_code, exception_entries): else: argrepr = "" yield Instruction( - "CACHE", CACHE, 0, None, argrepr, offset, offset, False, None, False, + "CACHE", CACHE, 0, None, argrepr, offset, offset, False, None, None, Positions(*next(co_positions, ())) ) -def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False): +def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False, + show_offsets=False): """Disassemble a code object.""" linestarts = dict(findlinestarts(co)) exception_entries = _parse_exception_table(co) @@ -693,10 +705,10 @@ def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False): co.co_names, co.co_consts, linestarts, file=file, exception_entries=exception_entries, co_positions=co.co_positions(), show_caches=show_caches, - original_code=co.co_code) + original_code=co.co_code, show_offsets=show_offsets) -def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adaptive=False): - disassemble(co, file=file, show_caches=show_caches, adaptive=adaptive) +def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adaptive=False, show_offsets=False): + disassemble(co, file=file, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) if depth is None or depth > 0: if depth is not None: depth = depth - 1 @@ -705,13 +717,15 @@ def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adap print(file=file) print("Disassembly of %r:" % (x,), file=file) _disassemble_recursive( - x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive + x, file=file, depth=depth, show_caches=show_caches, + adaptive=adaptive, show_offsets=show_offsets ) def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, names=None, co_consts=None, linestarts=None, *, file=None, line_offset=0, exception_entries=(), - co_positions=None, show_caches=False, original_code=None): + co_positions=None, show_caches=False, original_code=None, + show_offsets=False): # Omit the line number column entirely if we have no line number info if bool(linestarts): linestarts_ints = [line for line in linestarts.values() if line is not None] @@ -730,11 +744,14 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, lineno_width = len(str(None)) else: lineno_width = 0 - maxoffset = len(code) - 2 - if maxoffset >= 10000: - offset_width = len(str(maxoffset)) + if show_offsets: + maxoffset = len(code) - 2 + if maxoffset >= 10000: + offset_width = len(str(maxoffset)) + else: + offset_width = 4 else: - offset_width = 4 + offset_width = 0 for instr in _get_instructions_bytes(code, varname_from_oparg, names, co_consts, linestarts, @@ -754,8 +771,6 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, # Each CACHE takes 2 bytes is_current_instr = instr.offset <= lasti \ <= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)]) - if instr.label is not None: - print(f"L{instr.label}:", file=file) print(instr._disassemble(lineno_width, is_current_instr, offset_width), file=file) if exception_entries: @@ -886,7 +901,7 @@ class Bytecode: Iterating over this yields the bytecode operations as Instruction instances. """ - def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False): + def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False, show_offsets=False): self.codeobj = co = _get_code_object(x) if first_line is None: self.first_line = co.co_firstlineno @@ -900,6 +915,7 @@ def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False self.exception_entries = _parse_exception_table(co) self.show_caches = show_caches self.adaptive = adaptive + self.show_offsets = show_offsets def __iter__(self): co = self.codeobj @@ -948,7 +964,8 @@ def dis(self): exception_entries=self.exception_entries, co_positions=co.co_positions(), show_caches=self.show_caches, - original_code=co.co_code) + original_code=co.co_code, + show_offsets=self.show_offsets) return output.getvalue() @@ -958,12 +975,14 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('-C', '--show-caches', action='store_true', help='show inline caches') + parser.add_argument('-O', '--show-offsets', action='store_true', + help='show instruction offsets') parser.add_argument('infile', type=argparse.FileType('rb'), nargs='?', default='-') args = parser.parse_args() with args.infile as infile: source = infile.read() code = compile(source, args.infile.name, "exec") - dis(code, show_caches=args.show_caches) + dis(code, show_caches=args.show_caches, show_offsets=args.show_offsets) if __name__ == "__main__": main() diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 26a90ac5bcda57..6589fc86f5b3bc 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -42,45 +42,45 @@ def cm(cls, x): cls.x = x == 1 dis_c_instance_method = """\ - %3d RESUME 0 - - %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (self) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (self) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ - RESUME 0 - LOAD_FAST 1 - LOAD_CONST 1 - COMPARE_OP 72 (==) - LOAD_FAST 0 - STORE_ATTR 0 - RETURN_CONST 0 + RESUME 0 + LOAD_FAST 1 + LOAD_CONST 1 + COMPARE_OP 72 (==) + LOAD_FAST 0 + STORE_ATTR 0 + RETURN_CONST 0 """ dis_c_class_method = """\ - %3d RESUME 0 - - %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (cls) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (cls) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ - %3d RESUME 0 + %3d RESUME 0 - %3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - STORE_FAST 0 (x) - RETURN_CONST 0 (None) + %3d LOAD_FAST 0 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + STORE_FAST 0 (x) + RETURN_CONST 0 (None) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -100,26 +100,26 @@ def _f(a): return 1 dis_f = """\ - %3d RESUME 0 + %3d RESUME 0 - %3d LOAD_GLOBAL 1 (print + NULL) - LOAD_FAST 0 (a) - CALL 1 - POP_TOP + %3d LOAD_GLOBAL 1 (print + NULL) + LOAD_FAST 0 (a) + CALL 1 + POP_TOP - %3d RETURN_CONST 1 (1) + %3d RETURN_CONST 1 (1) """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) dis_f_co_code = """\ - RESUME 0 - LOAD_GLOBAL 1 - LOAD_FAST 0 - CALL 1 - POP_TOP - RETURN_CONST 1 + RESUME 0 + LOAD_GLOBAL 1 + LOAD_FAST 0 + CALL 1 + POP_TOP + RETURN_CONST 1 """ @@ -129,24 +129,22 @@ def bug708901(): pass dis_bug708901 = """\ - %3d RESUME 0 + %3d RESUME 0 - %3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) + %3d LOAD_GLOBAL 1 (range + NULL) + LOAD_CONST 1 (1) - %3d LOAD_CONST 2 (10) + %3d LOAD_CONST 2 (10) - %3d CALL 2 - GET_ITER -L1: - FOR_ITER 3 (to L2) - STORE_FAST 0 (res) + %3d CALL 2 + GET_ITER +L1: FOR_ITER 3 (to L2) + STORE_FAST 0 (res) - %3d JUMP_BACKWARD 5 (to L1) + %3d JUMP_BACKWARD 5 (to L1) -L2: - %3d END_FOR - RETURN_CONST 0 (None) +L2: %3d END_FOR + RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -161,20 +159,20 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ - %3d RESUME 0 + %3d RESUME 0 - %3d LOAD_ASSERTION_ERROR - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - LOAD_FAST 0 (x) - GET_ITER - CALL 0 + %3d LOAD_ASSERTION_ERROR + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + LOAD_FAST 0 (x) + GET_ITER + CALL 0 - %3d LOAD_CONST 2 (1) + %3d LOAD_CONST 2 (1) - %3d BINARY_OP 0 (+) - CALL 0 - RAISE_VARARGS 1 + %3d BINARY_OP 0 (+) + CALL 0 + RAISE_VARARGS 1 """ % (bug1333982.__code__.co_firstlineno, bug1333982.__code__.co_firstlineno + 1, __file__, @@ -192,8 +190,8 @@ def bug42562(): dis_bug42562 = """\ - RESUME 0 - RETURN_CONST 0 (None) + RESUME 0 + RETURN_CONST 0 (None) """ # Extended arg followed by NOP @@ -206,11 +204,11 @@ def bug42562(): ]) dis_bug_45757 = """\ - EXTENDED_ARG 1 - NOP - EXTENDED_ARG 1 - LOAD_CONST 297 - RETURN_VALUE + EXTENDED_ARG 1 + NOP + EXTENDED_ARG 1 + LOAD_CONST 297 + RETURN_VALUE """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -223,11 +221,10 @@ def bug42562(): dis_bug46724 = """\ -L1: - EXTENDED_ARG 255 - EXTENDED_ARG 65535 - EXTENDED_ARG 16777215 - JUMP_FORWARD -4 (to L1) +L1: EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to L1) """ def func_w_kwargs(a, b, **c): @@ -237,96 +234,96 @@ def wrap_func_w_kwargs(): func_w_kwargs(1, 2, c=5) dis_kw_names = """\ - %3d RESUME 0 - - %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_CONST 1 (1) - LOAD_CONST 2 (2) - LOAD_CONST 3 (5) - LOAD_CONST 4 (('c',)) - CALL_KW 3 - POP_TOP - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) + LOAD_CONST 1 (1) + LOAD_CONST 2 (2) + LOAD_CONST 3 (5) + LOAD_CONST 4 (('c',)) + CALL_KW 3 + POP_TOP + RETURN_CONST 0 (None) """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) dis_intrinsic_1_2 = """\ - 0 RESUME 0 - - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) - IMPORT_NAME 0 (math) - CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) - POP_TOP - RETURN_CONST 2 (None) + 0 RESUME 0 + + 1 LOAD_CONST 0 (0) + LOAD_CONST 1 (('*',)) + IMPORT_NAME 0 (math) + CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) + POP_TOP + RETURN_CONST 2 (None) """ dis_intrinsic_1_5 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (a) - CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE + 1 LOAD_NAME 0 (a) + CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) + RETURN_VALUE """ dis_intrinsic_1_6 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 BUILD_LIST 0 - LOAD_NAME 0 (a) - LIST_EXTEND 1 - CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE + 1 BUILD_LIST 0 + LOAD_NAME 0 (a) + LIST_EXTEND 1 + CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) + RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ - 1 RESUME 0 + 1 RESUME 0 - %3d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) + %3d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ _BIG_LINENO_FORMAT2 = """\ - 1 RESUME 0 + 1 RESUME 0 - %4d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) + %4d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ dis_module_expected_results = """\ Disassembly of f: - 4 RESUME 0 - RETURN_CONST 0 (None) + 4 RESUME 0 + RETURN_CONST 0 (None) Disassembly of g: - 5 RESUME 0 - RETURN_CONST 0 (None) + 5 RESUME 0 + RETURN_CONST 0 (None) """ expr_str = "x + 1" dis_expr_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - RETURN_VALUE + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + RETURN_VALUE """ simple_stmt_str = "x = x + 1" dis_simple_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - STORE_NAME 0 (x) - RETURN_CONST 1 (None) + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + STORE_NAME 0 (x) + RETURN_CONST 1 (None) """ annot_stmt_str = """\ @@ -338,34 +335,34 @@ def wrap_func_w_kwargs(): # leading newline is for a reason (tests lineno) dis_annot_stmt_str = """\ - 0 RESUME 0 - - 2 SETUP_ANNOTATIONS - LOAD_CONST 0 (1) - STORE_NAME 0 (x) - LOAD_NAME 1 (int) - LOAD_NAME 2 (__annotations__) - LOAD_CONST 1 ('x') - STORE_SUBSCR - - 3 LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 0 (1) - CALL 1 - LOAD_NAME 2 (__annotations__) - LOAD_CONST 2 ('y') - STORE_SUBSCR - - 4 LOAD_CONST 0 (1) - LOAD_NAME 4 (lst) - LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 3 (0) - CALL 1 - STORE_SUBSCR - LOAD_NAME 1 (int) - POP_TOP - RETURN_CONST 4 (None) + 0 RESUME 0 + + 2 SETUP_ANNOTATIONS + LOAD_CONST 0 (1) + STORE_NAME 0 (x) + LOAD_NAME 1 (int) + LOAD_NAME 2 (__annotations__) + LOAD_CONST 1 ('x') + STORE_SUBSCR + + 3 LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 0 (1) + CALL 1 + LOAD_NAME 2 (__annotations__) + LOAD_CONST 2 ('y') + STORE_SUBSCR + + 4 LOAD_CONST 0 (1) + LOAD_NAME 4 (lst) + LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 3 (0) + CALL 1 + STORE_SUBSCR + LOAD_NAME 1 (int) + POP_TOP + RETURN_CONST 4 (None) """ compound_stmt_str = """\ @@ -375,71 +372,62 @@ def wrap_func_w_kwargs(): # Trailing newline has been deliberately omitted dis_compound_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_CONST 0 (0) - STORE_NAME 0 (x) + 1 LOAD_CONST 0 (0) + STORE_NAME 0 (x) - 2 NOP + 2 NOP -L1: - 3 LOAD_NAME 0 (x) - LOAD_CONST 1 (1) - BINARY_OP 13 (+=) - STORE_NAME 0 (x) +L1: 3 LOAD_NAME 0 (x) + LOAD_CONST 1 (1) + BINARY_OP 13 (+=) + STORE_NAME 0 (x) - 2 JUMP_BACKWARD 7 (to L1) + 2 JUMP_BACKWARD 7 (to L1) """ dis_traceback = """\ - %4d RESUME 0 + %4d RESUME 0 - %4d NOP + %4d NOP -L1: - %4d LOAD_CONST 1 (1) - LOAD_CONST 2 (0) - --> BINARY_OP 11 (/) - POP_TOP +L1: %4d LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP -L2: - %4d LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE +L2: %4d LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE -L3: - None PUSH_EXC_INFO - - %4d LOAD_GLOBAL 0 (Exception) - CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to L7) - STORE_FAST 0 (e) - -L4: - %4d LOAD_FAST 0 (e) - LOAD_ATTR 2 (__traceback__) - STORE_FAST 1 (tb) -L5: - POP_EXCEPT - LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - - %4d LOAD_FAST 1 (tb) - RETURN_VALUE +L3: None PUSH_EXC_INFO + + %4d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to L7) + STORE_FAST 0 (e) + +L4: %4d LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) +L5: POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) -L6: - None LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - RERAISE 1 + %4d LOAD_FAST 1 (tb) + RETURN_VALUE -L7: - %4d RERAISE 0 +L6: None LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 -L8: - None COPY 3 - POP_EXCEPT - RERAISE 1 +L7: %4d RERAISE 0 + +L8: None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L3 [0] L3 to L4 -> L8 [1] lasti @@ -458,25 +446,25 @@ def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' dis_fstring = """\ - %3d RESUME 0 - - %3d LOAD_FAST 0 (a) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 1 (b) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - LOAD_CONST 1 (' ') - LOAD_FAST 2 (c) - CONVERT_VALUE 2 (repr) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 3 (d) - CONVERT_VALUE 2 (repr) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - BUILD_STRING 7 - RETURN_VALUE + %3d RESUME 0 + + %3d LOAD_FAST 0 (a) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 1 (b) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + LOAD_CONST 1 (' ') + LOAD_FAST 2 (c) + CONVERT_VALUE 2 (repr) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 3 (d) + CONVERT_VALUE 2 (repr) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + BUILD_STRING 7 + RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -485,48 +473,42 @@ def _with(c): y = 2 dis_with = """\ - %4d RESUME 0 - - %4d LOAD_FAST 0 (c) - BEFORE_WITH -L1: - POP_TOP - - %4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -L2: - %4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L3: - %4d PUSH_EXC_INFO - WITH_EXCEPT_START - TO_BOOL - POP_JUMP_IF_TRUE 1 (to L4) - RERAISE 2 -L4: - POP_TOP -L5: - POP_EXCEPT - POP_TOP - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L6: - None COPY 3 - POP_EXCEPT - RERAISE 1 + %4d RESUME 0 + + %4d LOAD_FAST 0 (c) + BEFORE_WITH +L1: POP_TOP + + %4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +L2: %4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L3: %4d PUSH_EXC_INFO + WITH_EXCEPT_START + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L4) + RERAISE 2 +L4: POP_TOP +L5: POP_EXCEPT + POP_TOP + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L6: None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L3 [1] lasti L3 to L5 -> L6 [3] lasti @@ -545,101 +527,76 @@ async def _asyncwith(c): y = 2 dis_asyncwith = """\ - %4d RETURN_GENERATOR - POP_TOP -L1: - RESUME 0 - - %4d LOAD_FAST 0 (c) - BEFORE_ASYNC_WITH - GET_AWAITABLE 1 - LOAD_CONST 0 (None) -L2: - SEND 3 (to L5) -L3: - YIELD_VALUE 1 -L4: - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) -L5: - END_SEND -L6: - POP_TOP - - %4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -L7: - %4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - GET_AWAITABLE 2 - LOAD_CONST 0 (None) -L8: - SEND 3 (to L11) -L9: - YIELD_VALUE 1 -L10: - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) -L11: - END_SEND - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L12: - %4d CLEANUP_THROW - -L13: - None JUMP_BACKWARD 26 (to L5) - -L14: - %4d CLEANUP_THROW - -L15: - None JUMP_BACKWARD 11 (to L11) - -L16: - %4d PUSH_EXC_INFO - WITH_EXCEPT_START - GET_AWAITABLE 2 - LOAD_CONST 0 (None) -L17: - SEND 4 (to L21) -L18: - YIELD_VALUE 1 -L19: - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) -L20: - CLEANUP_THROW -L21: - END_SEND - TO_BOOL - POP_JUMP_IF_TRUE 1 (to L22) - RERAISE 2 -L22: - POP_TOP -L23: - POP_EXCEPT - POP_TOP - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L24: - None COPY 3 - POP_EXCEPT - RERAISE 1 -L25: - CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 + %4d RETURN_GENERATOR + POP_TOP +L1: RESUME 0 + + %4d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) +L2: SEND 3 (to L5) +L3: YIELD_VALUE 1 +L4: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) +L5: END_SEND +L6: POP_TOP + + %4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +L7: %4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) +L8: SEND 3 (to L11) +L9: YIELD_VALUE 1 +L10: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) +L11: END_SEND + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L12: %4d CLEANUP_THROW + +L13: None JUMP_BACKWARD 26 (to L5) + +L14: %4d CLEANUP_THROW + +L15: None JUMP_BACKWARD 11 (to L11) + +L16: %4d PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) +L17: SEND 4 (to L21) +L18: YIELD_VALUE 1 +L19: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) +L20: CLEANUP_THROW +L21: END_SEND + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L22) + RERAISE 2 +L22: POP_TOP +L23: POP_EXCEPT + POP_TOP + POP_TOP + + %4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +L24: None COPY 3 + POP_EXCEPT + RERAISE 1 +L25: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: L1 to L3 -> L25 [0] lasti L3 to L4 -> L12 [3] @@ -678,33 +635,29 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ - %4d RESUME 0 + %4d RESUME 0 - %4d NOP + %4d NOP -L1: - %4d LOAD_FAST 0 (a) +L1: %4d LOAD_FAST 0 (a) -L2: - %4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_VALUE +L2: %4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_VALUE -L3: - None PUSH_EXC_INFO +L3: None PUSH_EXC_INFO - %4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 + %4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -L4: - None COPY 3 - POP_EXCEPT - RERAISE 1 +L4: None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L3 [0] L3 to L4 -> L4 [1] lasti @@ -716,31 +669,29 @@ def _tryfinallyconst(b): ) dis_tryfinallyconst = """\ - %4d RESUME 0 + %4d RESUME 0 - %4d NOP + %4d NOP - %4d NOP + %4d NOP - %4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_CONST 1 (1) + %4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_CONST 1 (1) -L1: - None PUSH_EXC_INFO +L1: None PUSH_EXC_INFO - %4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 + %4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -L2: - None COPY 3 - POP_EXCEPT - RERAISE 1 +L2: None COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L2 [1] lasti """ % (_tryfinallyconst.__code__.co_firstlineno, @@ -767,19 +718,19 @@ def foo(x): return foo dis_nested_0 = """\ - None MAKE_CELL 0 (y) + None MAKE_CELL 0 (y) - %4d RESUME 0 + %4d RESUME 0 - %4d LOAD_FAST 0 (y) - BUILD_TUPLE 1 - LOAD_CONST 1 () - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - STORE_FAST 1 (foo) + %4d LOAD_FAST 0 (y) + BUILD_TUPLE 1 + LOAD_CONST 1 () + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + STORE_FAST 1 (foo) - %4d LOAD_FAST 1 (foo) - RETURN_VALUE + %4d LOAD_FAST 1 (foo) + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -789,22 +740,22 @@ def foo(x): dis_nested_1 = """%s Disassembly of : - None COPY_FREE_VARS 1 - MAKE_CELL 0 (x) - - %4d RESUME 0 - - %4d LOAD_GLOBAL 1 (list + NULL) - LOAD_FAST 0 (x) - BUILD_TUPLE 1 - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - LOAD_DEREF 1 (y) - GET_ITER - CALL 0 - CALL 1 - RETURN_VALUE + None COPY_FREE_VARS 1 + MAKE_CELL 0 (x) + + %4d RESUME 0 + + %4d LOAD_GLOBAL 1 (list + NULL) + LOAD_FAST 0 (x) + BUILD_TUPLE 1 + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + LOAD_DEREF 1 (y) + GET_ITER + CALL 0 + CALL 1 + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -816,30 +767,26 @@ def foo(x): dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: - None COPY_FREE_VARS 1 - - %4d RETURN_GENERATOR - POP_TOP -L1: - RESUME 0 - LOAD_FAST 0 (.0) -L2: - FOR_ITER 10 (to L3) - STORE_FAST 1 (z) - LOAD_DEREF 2 (x) - LOAD_FAST 1 (z) - BINARY_OP 0 (+) - YIELD_VALUE 0 - RESUME 5 - POP_TOP - JUMP_BACKWARD 12 (to L2) -L3: - END_FOR - RETURN_CONST 0 (None) - -L4: - None CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 + None COPY_FREE_VARS 1 + + %4d RETURN_GENERATOR + POP_TOP +L1: RESUME 0 + LOAD_FAST 0 (.0) +L2: FOR_ITER 10 (to L3) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + YIELD_VALUE 0 + RESUME 5 + POP_TOP + JUMP_BACKWARD 12 (to L2) +L3: END_FOR + RETURN_CONST 0 (None) + +L4: None CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: L1 to L4 -> L4 [0] lasti """ % (dis_nested_1, @@ -853,14 +800,14 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ - %3d RESUME_CHECK 0 + %3d RESUME_CHECK 0 - %3d LOAD_FAST_LOAD_FAST 1 (x, y) - STORE_FAST_STORE_FAST 50 (b, a) + %3d LOAD_FAST_LOAD_FAST 1 (x, y) + STORE_FAST_STORE_FAST 50 (b, a) - %3d LOAD_FAST_LOAD_FAST 35 (a, b) - BUILD_TUPLE 2 - RETURN_VALUE + %3d LOAD_FAST_LOAD_FAST 35 (a, b) + BUILD_TUPLE 2 + RETURN_VALUE """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -870,27 +817,25 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ - %3d RESUME_CHECK 0 - - %3d BUILD_LIST 0 - LOAD_CONST 1 ((1, 2, 3)) - LIST_EXTEND 1 - LOAD_CONST 2 (3) - BINARY_OP 5 (*) - GET_ITER -L1: - FOR_ITER_LIST 14 (to L2) - STORE_FAST 0 (i) - - %3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) - LOAD_FAST 0 (i) - CALL_PY_WITH_DEFAULTS 1 - POP_TOP - JUMP_BACKWARD 16 (to L1) - -L2: - %3d END_FOR - RETURN_CONST 0 (None) + %3d RESUME_CHECK 0 + + %3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER +L1: FOR_ITER_LIST 14 (to L2) + STORE_FAST 0 (i) + + %3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 16 (to L1) + +L2: %3d END_FOR + RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -900,14 +845,14 @@ def extended_arg_quick(): *_, _ = ... dis_extended_arg_quick_code = """\ - %3d RESUME 0 - - %3d LOAD_CONST 1 (Ellipsis) - EXTENDED_ARG 1 - UNPACK_EX 256 - POP_TOP - STORE_FAST 0 (_) - RETURN_CONST 0 (None) + %3d RESUME 0 + + %3d LOAD_CONST 1 (Ellipsis) + EXTENDED_ARG 1 + UNPACK_EX 256 + POP_TOP + STORE_FAST 0 (_) + RETURN_CONST 0 (None) """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -1172,12 +1117,12 @@ def test_super_instructions(self): @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (a) - LOAD_NAME 1 (b) - %s - RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_NAME 1 (b) + %s + RETURN_VALUE """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) @@ -1190,12 +1135,12 @@ def test_binary_specialize(self): self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)") binary_subscr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (a) - LOAD_CONST 0 (0) - %s - RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_CONST 0 (0) + %s + RETURN_VALUE """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) @@ -1211,11 +1156,11 @@ def test_binary_specialize(self): @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_CONST 0 ('a') - LOAD_ATTR_SLOT 0 (__class__) - RETURN_VALUE + 1 LOAD_CONST 0 ('a') + LOAD_ATTR_SLOT 0 (__class__) + RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1226,13 +1171,13 @@ def test_load_attr_specialize(self): @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (str) - PUSH_NULL - LOAD_CONST 0 (1) - CALL_STR_1 1 - RETURN_VALUE + 1 LOAD_NAME 0 (str) + PUSH_NULL + LOAD_CONST 0 (1) + CALL_STR_1 1 + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) From 020c74204bf072d5a57d713dc0e5609d6ed524e5 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Tue, 21 Nov 2023 01:29:33 +0000 Subject: [PATCH 13/24] fix doctest --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 9329a0ad87eb88..8bdb0efd806990 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -62,12 +62,12 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 - 3 LOAD_GLOBAL 1 (len + NULL) - LOAD_FAST 0 (alist) - CALL 1 - RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + RETURN_VALUE (The "2" is a line number). From 965a3cd6ec9ccdce7165d84d7ff593598944bec8 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 12:20:30 +0000 Subject: [PATCH 14/24] linenumber, then labels, then (optionally) offsets --- Lib/dis.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index a0f5fa2a8d25ad..0475888c6d8146 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -337,7 +337,7 @@ class Instruction(_Instruction): @staticmethod def _get_argval_argrepr(op, arg, offset, co_consts, names, varname_from_oparg, - labels_map, label_width): + labels_map): get_name = None if names is None else names.__getitem__ argval = None argrepr = '' @@ -409,11 +409,10 @@ def _create(cls, op, arg, offset, start_offset, starts_line, line_number, co_consts=None, varname_from_oparg=None, names=None, labels_map=None, exceptions_map=None): - label_width = len(str(len(labels_map))) + label_width = 4 + len(str(len(labels_map))) argval, argrepr = cls._get_argval_argrepr( op, arg, offset, - co_consts, names, varname_from_oparg, labels_map, - label_width) + co_consts, names, varname_from_oparg, labels_map) label = labels_map.get(offset, None) instr = Instruction(_all_opname[op], op, arg, argval, argrepr, offset, start_offset, starts_line, line_number, @@ -466,8 +465,7 @@ def is_jump_target(self): """True if other code jumps to here, otherwise False""" return self.label is not None - def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0, - label_width=4): + def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0): """Format instruction details for inclusion in disassembly output. *lineno_width* sets the width of the line number field (0 omits it) @@ -476,12 +474,6 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0, """ fields = [] # - # Column: Label - if self.label is not None: - lbl = f"L{self.label}:" - fields.append(f"{lbl:<{label_width}}") - else: - fields.append(' ' * label_width) # Column: Source code line number if lineno_width: if self.starts_line: @@ -490,14 +482,20 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0, fields.append(lineno_fmt % self.line_number) else: fields.append(' ' * lineno_width) + # Column: Label + if self.label is not None: + lbl = f"L{self.label}:" + fields.append(f"{lbl:>{self.label_width}}") + else: + fields.append(' ' * self.label_width) + # Column: Instruction offset from start of code sequence + if offset_width > 0: + fields.append(f"{repr(self.offset):>{offset_width}} ") # Column: Current instruction indicator if mark_as_current: fields.append('-->') else: fields.append(' ') - # Column: Instruction offset from start of code sequence - if offset_width > 0: - fields.append(f"{repr(self.offset):>{offset_width}} ") # Column: Opcode name fields.append(self.opname.ljust(_OPNAME_WIDTH)) # Column: Opcode argument From 7d00ddbd81099d003709064b9d355aef52a8af57 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 13:35:13 +0000 Subject: [PATCH 15/24] update tests --- Lib/test/test_dis.py | 902 +++++++++++++++++++++---------------------- 1 file changed, 451 insertions(+), 451 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 6589fc86f5b3bc..d0d454fa42bac3 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -42,45 +42,45 @@ def cm(cls, x): cls.x = x == 1 dis_c_instance_method = """\ - %3d RESUME 0 - - %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (self) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (self) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ - RESUME 0 - LOAD_FAST 1 - LOAD_CONST 1 - COMPARE_OP 72 (==) - LOAD_FAST 0 - STORE_ATTR 0 - RETURN_CONST 0 + RESUME 0 + LOAD_FAST 1 + LOAD_CONST 1 + COMPARE_OP 72 (==) + LOAD_FAST 0 + STORE_ATTR 0 + RETURN_CONST 0 """ dis_c_class_method = """\ - %3d RESUME 0 - - %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (cls) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (cls) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ - %3d RESUME 0 +%3d RESUME 0 - %3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - STORE_FAST 0 (x) - RETURN_CONST 0 (None) +%3d LOAD_FAST 0 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + STORE_FAST 0 (x) + RETURN_CONST 0 (None) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -100,26 +100,26 @@ def _f(a): return 1 dis_f = """\ - %3d RESUME 0 +%3d RESUME 0 - %3d LOAD_GLOBAL 1 (print + NULL) - LOAD_FAST 0 (a) - CALL 1 - POP_TOP +%3d LOAD_GLOBAL 1 (print + NULL) + LOAD_FAST 0 (a) + CALL 1 + POP_TOP - %3d RETURN_CONST 1 (1) +%3d RETURN_CONST 1 (1) """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) dis_f_co_code = """\ - RESUME 0 - LOAD_GLOBAL 1 - LOAD_FAST 0 - CALL 1 - POP_TOP - RETURN_CONST 1 + RESUME 0 + LOAD_GLOBAL 1 + LOAD_FAST 0 + CALL 1 + POP_TOP + RETURN_CONST 1 """ @@ -129,22 +129,22 @@ def bug708901(): pass dis_bug708901 = """\ - %3d RESUME 0 +%3d RESUME 0 - %3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) +%3d LOAD_GLOBAL 1 (range + NULL) + LOAD_CONST 1 (1) - %3d LOAD_CONST 2 (10) +%3d LOAD_CONST 2 (10) - %3d CALL 2 - GET_ITER -L1: FOR_ITER 3 (to L2) - STORE_FAST 0 (res) +%3d CALL 2 + GET_ITER + L1: FOR_ITER 3 (to L2) + STORE_FAST 0 (res) - %3d JUMP_BACKWARD 5 (to L1) +%3d JUMP_BACKWARD 5 (to L1) -L2: %3d END_FOR - RETURN_CONST 0 (None) +%3d L2: END_FOR + RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -159,20 +159,20 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ - %3d RESUME 0 +%3d RESUME 0 - %3d LOAD_ASSERTION_ERROR - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - LOAD_FAST 0 (x) - GET_ITER - CALL 0 +%3d LOAD_ASSERTION_ERROR + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + LOAD_FAST 0 (x) + GET_ITER + CALL 0 - %3d LOAD_CONST 2 (1) +%3d LOAD_CONST 2 (1) - %3d BINARY_OP 0 (+) - CALL 0 - RAISE_VARARGS 1 +%3d BINARY_OP 0 (+) + CALL 0 + RAISE_VARARGS 1 """ % (bug1333982.__code__.co_firstlineno, bug1333982.__code__.co_firstlineno + 1, __file__, @@ -190,8 +190,8 @@ def bug42562(): dis_bug42562 = """\ - RESUME 0 - RETURN_CONST 0 (None) + RESUME 0 + RETURN_CONST 0 (None) """ # Extended arg followed by NOP @@ -204,11 +204,11 @@ def bug42562(): ]) dis_bug_45757 = """\ - EXTENDED_ARG 1 - NOP - EXTENDED_ARG 1 - LOAD_CONST 297 - RETURN_VALUE + EXTENDED_ARG 1 + NOP + EXTENDED_ARG 1 + LOAD_CONST 297 + RETURN_VALUE """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -221,10 +221,10 @@ def bug42562(): dis_bug46724 = """\ -L1: EXTENDED_ARG 255 - EXTENDED_ARG 65535 - EXTENDED_ARG 16777215 - JUMP_FORWARD -4 (to L1) + L1: EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to L1) """ def func_w_kwargs(a, b, **c): @@ -234,96 +234,96 @@ def wrap_func_w_kwargs(): func_w_kwargs(1, 2, c=5) dis_kw_names = """\ - %3d RESUME 0 - - %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_CONST 1 (1) - LOAD_CONST 2 (2) - LOAD_CONST 3 (5) - LOAD_CONST 4 (('c',)) - CALL_KW 3 - POP_TOP - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) + LOAD_CONST 1 (1) + LOAD_CONST 2 (2) + LOAD_CONST 3 (5) + LOAD_CONST 4 (('c',)) + CALL_KW 3 + POP_TOP + RETURN_CONST 0 (None) """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) dis_intrinsic_1_2 = """\ - 0 RESUME 0 - - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) - IMPORT_NAME 0 (math) - CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) - POP_TOP - RETURN_CONST 2 (None) + 0 RESUME 0 + + 1 LOAD_CONST 0 (0) + LOAD_CONST 1 (('*',)) + IMPORT_NAME 0 (math) + CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) + POP_TOP + RETURN_CONST 2 (None) """ dis_intrinsic_1_5 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (a) - CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE + 1 LOAD_NAME 0 (a) + CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) + RETURN_VALUE """ dis_intrinsic_1_6 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 BUILD_LIST 0 - LOAD_NAME 0 (a) - LIST_EXTEND 1 - CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE + 1 BUILD_LIST 0 + LOAD_NAME 0 (a) + LIST_EXTEND 1 + CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) + RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ - 1 RESUME 0 + 1 RESUME 0 - %3d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) +%3d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ _BIG_LINENO_FORMAT2 = """\ - 1 RESUME 0 + 1 RESUME 0 - %4d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) +%4d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ dis_module_expected_results = """\ Disassembly of f: - 4 RESUME 0 - RETURN_CONST 0 (None) + 4 RESUME 0 + RETURN_CONST 0 (None) Disassembly of g: - 5 RESUME 0 - RETURN_CONST 0 (None) + 5 RESUME 0 + RETURN_CONST 0 (None) """ expr_str = "x + 1" dis_expr_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - RETURN_VALUE + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + RETURN_VALUE """ simple_stmt_str = "x = x + 1" dis_simple_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - STORE_NAME 0 (x) - RETURN_CONST 1 (None) + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + STORE_NAME 0 (x) + RETURN_CONST 1 (None) """ annot_stmt_str = """\ @@ -335,34 +335,34 @@ def wrap_func_w_kwargs(): # leading newline is for a reason (tests lineno) dis_annot_stmt_str = """\ - 0 RESUME 0 - - 2 SETUP_ANNOTATIONS - LOAD_CONST 0 (1) - STORE_NAME 0 (x) - LOAD_NAME 1 (int) - LOAD_NAME 2 (__annotations__) - LOAD_CONST 1 ('x') - STORE_SUBSCR - - 3 LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 0 (1) - CALL 1 - LOAD_NAME 2 (__annotations__) - LOAD_CONST 2 ('y') - STORE_SUBSCR - - 4 LOAD_CONST 0 (1) - LOAD_NAME 4 (lst) - LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 3 (0) - CALL 1 - STORE_SUBSCR - LOAD_NAME 1 (int) - POP_TOP - RETURN_CONST 4 (None) + 0 RESUME 0 + + 2 SETUP_ANNOTATIONS + LOAD_CONST 0 (1) + STORE_NAME 0 (x) + LOAD_NAME 1 (int) + LOAD_NAME 2 (__annotations__) + LOAD_CONST 1 ('x') + STORE_SUBSCR + + 3 LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 0 (1) + CALL 1 + LOAD_NAME 2 (__annotations__) + LOAD_CONST 2 ('y') + STORE_SUBSCR + + 4 LOAD_CONST 0 (1) + LOAD_NAME 4 (lst) + LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 3 (0) + CALL 1 + STORE_SUBSCR + LOAD_NAME 1 (int) + POP_TOP + RETURN_CONST 4 (None) """ compound_stmt_str = """\ @@ -372,62 +372,62 @@ def wrap_func_w_kwargs(): # Trailing newline has been deliberately omitted dis_compound_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_CONST 0 (0) - STORE_NAME 0 (x) + 1 LOAD_CONST 0 (0) + STORE_NAME 0 (x) - 2 NOP + 2 NOP -L1: 3 LOAD_NAME 0 (x) - LOAD_CONST 1 (1) - BINARY_OP 13 (+=) - STORE_NAME 0 (x) + 3 L1: LOAD_NAME 0 (x) + LOAD_CONST 1 (1) + BINARY_OP 13 (+=) + STORE_NAME 0 (x) - 2 JUMP_BACKWARD 7 (to L1) + 2 JUMP_BACKWARD 7 (to L1) """ dis_traceback = """\ - %4d RESUME 0 +%4d RESUME 0 - %4d NOP +%4d NOP -L1: %4d LOAD_CONST 1 (1) - LOAD_CONST 2 (0) - --> BINARY_OP 11 (/) - POP_TOP +%4d L1: LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP -L2: %4d LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE +%4d L2: LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE -L3: None PUSH_EXC_INFO +None L3: PUSH_EXC_INFO - %4d LOAD_GLOBAL 0 (Exception) - CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to L7) - STORE_FAST 0 (e) +%4d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to L7) + STORE_FAST 0 (e) -L4: %4d LOAD_FAST 0 (e) - LOAD_ATTR 2 (__traceback__) - STORE_FAST 1 (tb) -L5: POP_EXCEPT - LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) +%4d L4: LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) + L5: POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) - %4d LOAD_FAST 1 (tb) - RETURN_VALUE +%4d LOAD_FAST 1 (tb) + RETURN_VALUE -L6: None LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - RERAISE 1 +None L6: LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 -L7: %4d RERAISE 0 +%4d L7: RERAISE 0 -L8: None COPY 3 - POP_EXCEPT - RERAISE 1 +None L8: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L3 [0] L3 to L4 -> L8 [1] lasti @@ -446,25 +446,25 @@ def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' dis_fstring = """\ - %3d RESUME 0 - - %3d LOAD_FAST 0 (a) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 1 (b) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - LOAD_CONST 1 (' ') - LOAD_FAST 2 (c) - CONVERT_VALUE 2 (repr) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 3 (d) - CONVERT_VALUE 2 (repr) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - BUILD_STRING 7 - RETURN_VALUE +%3d RESUME 0 + +%3d LOAD_FAST 0 (a) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 1 (b) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + LOAD_CONST 1 (' ') + LOAD_FAST 2 (c) + CONVERT_VALUE 2 (repr) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 3 (d) + CONVERT_VALUE 2 (repr) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + BUILD_STRING 7 + RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -473,42 +473,42 @@ def _with(c): y = 2 dis_with = """\ - %4d RESUME 0 - - %4d LOAD_FAST 0 (c) - BEFORE_WITH -L1: POP_TOP - - %4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -L2: %4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L3: %4d PUSH_EXC_INFO - WITH_EXCEPT_START - TO_BOOL - POP_JUMP_IF_TRUE 1 (to L4) - RERAISE 2 -L4: POP_TOP -L5: POP_EXCEPT - POP_TOP - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L6: None COPY 3 - POP_EXCEPT - RERAISE 1 +%4d RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_WITH + L1: POP_TOP + +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d L2: LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%4d L3: PUSH_EXC_INFO + WITH_EXCEPT_START + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L4) + RERAISE 2 + L4: POP_TOP + L5: POP_EXCEPT + POP_TOP + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +None L6: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L3 [1] lasti L3 to L5 -> L6 [3] lasti @@ -527,76 +527,76 @@ async def _asyncwith(c): y = 2 dis_asyncwith = """\ - %4d RETURN_GENERATOR - POP_TOP -L1: RESUME 0 - - %4d LOAD_FAST 0 (c) - BEFORE_ASYNC_WITH - GET_AWAITABLE 1 - LOAD_CONST 0 (None) -L2: SEND 3 (to L5) -L3: YIELD_VALUE 1 -L4: RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) -L5: END_SEND -L6: POP_TOP - - %4d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -L7: %4d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - GET_AWAITABLE 2 - LOAD_CONST 0 (None) -L8: SEND 3 (to L11) -L9: YIELD_VALUE 1 -L10: RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) -L11: END_SEND - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L12: %4d CLEANUP_THROW - -L13: None JUMP_BACKWARD 26 (to L5) - -L14: %4d CLEANUP_THROW - -L15: None JUMP_BACKWARD 11 (to L11) - -L16: %4d PUSH_EXC_INFO - WITH_EXCEPT_START - GET_AWAITABLE 2 - LOAD_CONST 0 (None) -L17: SEND 4 (to L21) -L18: YIELD_VALUE 1 -L19: RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) -L20: CLEANUP_THROW -L21: END_SEND - TO_BOOL - POP_JUMP_IF_TRUE 1 (to L22) - RERAISE 2 -L22: POP_TOP -L23: POP_EXCEPT - POP_TOP - POP_TOP - - %4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -L24: None COPY 3 - POP_EXCEPT - RERAISE 1 -L25: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 +%4d RETURN_GENERATOR + POP_TOP + L1: RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) + L2: SEND 3 (to L5) + L3: YIELD_VALUE 1 + L4: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) + L5: END_SEND + L6: POP_TOP + +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d L7: LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + L8: SEND 3 (to L11) + L9: YIELD_VALUE 1 + L10: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) + L11: END_SEND + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%4d L12: CLEANUP_THROW + +None L13: JUMP_BACKWARD 26 (to L5) + +%4d L14: CLEANUP_THROW + +None L15: JUMP_BACKWARD 11 (to L11) + +%4d L16: PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + L17: SEND 4 (to L21) + L18: YIELD_VALUE 1 + L19: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) + L20: CLEANUP_THROW + L21: END_SEND + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L22) + RERAISE 2 + L22: POP_TOP + L23: POP_EXCEPT + POP_TOP + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +None L24: COPY 3 + POP_EXCEPT + RERAISE 1 + L25: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: L1 to L3 -> L25 [0] lasti L3 to L4 -> L12 [3] @@ -635,29 +635,29 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ - %4d RESUME 0 +%4d RESUME 0 - %4d NOP +%4d NOP -L1: %4d LOAD_FAST 0 (a) +%4d L1: LOAD_FAST 0 (a) -L2: %4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_VALUE +%4d L2: LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_VALUE -L3: None PUSH_EXC_INFO +None L3: PUSH_EXC_INFO - %4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 +%4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -L4: None COPY 3 - POP_EXCEPT - RERAISE 1 +None L4: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L3 [0] L3 to L4 -> L4 [1] lasti @@ -669,29 +669,29 @@ def _tryfinallyconst(b): ) dis_tryfinallyconst = """\ - %4d RESUME 0 +%4d RESUME 0 - %4d NOP +%4d NOP - %4d NOP +%4d NOP - %4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_CONST 1 (1) +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_CONST 1 (1) -L1: None PUSH_EXC_INFO +None L1: PUSH_EXC_INFO - %4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -L2: None COPY 3 - POP_EXCEPT - RERAISE 1 +None L2: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: L1 to L2 -> L2 [1] lasti """ % (_tryfinallyconst.__code__.co_firstlineno, @@ -718,19 +718,19 @@ def foo(x): return foo dis_nested_0 = """\ - None MAKE_CELL 0 (y) +None MAKE_CELL 0 (y) - %4d RESUME 0 +%4d RESUME 0 - %4d LOAD_FAST 0 (y) - BUILD_TUPLE 1 - LOAD_CONST 1 () - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - STORE_FAST 1 (foo) +%4d LOAD_FAST 0 (y) + BUILD_TUPLE 1 + LOAD_CONST 1 () + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + STORE_FAST 1 (foo) - %4d LOAD_FAST 1 (foo) - RETURN_VALUE +%4d LOAD_FAST 1 (foo) + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -740,22 +740,22 @@ def foo(x): dis_nested_1 = """%s Disassembly of : - None COPY_FREE_VARS 1 - MAKE_CELL 0 (x) - - %4d RESUME 0 - - %4d LOAD_GLOBAL 1 (list + NULL) - LOAD_FAST 0 (x) - BUILD_TUPLE 1 - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - LOAD_DEREF 1 (y) - GET_ITER - CALL 0 - CALL 1 - RETURN_VALUE +None COPY_FREE_VARS 1 + MAKE_CELL 0 (x) + +%4d RESUME 0 + +%4d LOAD_GLOBAL 1 (list + NULL) + LOAD_FAST 0 (x) + BUILD_TUPLE 1 + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + LOAD_DEREF 1 (y) + GET_ITER + CALL 0 + CALL 1 + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -767,26 +767,26 @@ def foo(x): dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: - None COPY_FREE_VARS 1 - - %4d RETURN_GENERATOR - POP_TOP -L1: RESUME 0 - LOAD_FAST 0 (.0) -L2: FOR_ITER 10 (to L3) - STORE_FAST 1 (z) - LOAD_DEREF 2 (x) - LOAD_FAST 1 (z) - BINARY_OP 0 (+) - YIELD_VALUE 0 - RESUME 5 - POP_TOP - JUMP_BACKWARD 12 (to L2) -L3: END_FOR - RETURN_CONST 0 (None) - -L4: None CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 +None COPY_FREE_VARS 1 + +%4d RETURN_GENERATOR + POP_TOP + L1: RESUME 0 + LOAD_FAST 0 (.0) + L2: FOR_ITER 10 (to L3) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + YIELD_VALUE 0 + RESUME 5 + POP_TOP + JUMP_BACKWARD 12 (to L2) + L3: END_FOR + RETURN_CONST 0 (None) + +None L4: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: L1 to L4 -> L4 [0] lasti """ % (dis_nested_1, @@ -800,14 +800,14 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ - %3d RESUME_CHECK 0 +%3d RESUME_CHECK 0 - %3d LOAD_FAST_LOAD_FAST 1 (x, y) - STORE_FAST_STORE_FAST 50 (b, a) +%3d LOAD_FAST_LOAD_FAST 1 (x, y) + STORE_FAST_STORE_FAST 50 (b, a) - %3d LOAD_FAST_LOAD_FAST 35 (a, b) - BUILD_TUPLE 2 - RETURN_VALUE +%3d LOAD_FAST_LOAD_FAST 35 (a, b) + BUILD_TUPLE 2 + RETURN_VALUE """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -817,25 +817,25 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ - %3d RESUME_CHECK 0 - - %3d BUILD_LIST 0 - LOAD_CONST 1 ((1, 2, 3)) - LIST_EXTEND 1 - LOAD_CONST 2 (3) - BINARY_OP 5 (*) - GET_ITER -L1: FOR_ITER_LIST 14 (to L2) - STORE_FAST 0 (i) - - %3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) - LOAD_FAST 0 (i) - CALL_PY_WITH_DEFAULTS 1 - POP_TOP - JUMP_BACKWARD 16 (to L1) - -L2: %3d END_FOR - RETURN_CONST 0 (None) +%3d RESUME_CHECK 0 + +%3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER + L1: FOR_ITER_LIST 14 (to L2) + STORE_FAST 0 (i) + +%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 16 (to L1) + +%3d L2: END_FOR + RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -845,14 +845,14 @@ def extended_arg_quick(): *_, _ = ... dis_extended_arg_quick_code = """\ - %3d RESUME 0 - - %3d LOAD_CONST 1 (Ellipsis) - EXTENDED_ARG 1 - UNPACK_EX 256 - POP_TOP - STORE_FAST 0 (_) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_CONST 1 (Ellipsis) + EXTENDED_ARG 1 + UNPACK_EX 256 + POP_TOP + STORE_FAST 0 (_) + RETURN_CONST 0 (None) """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -1117,12 +1117,12 @@ def test_super_instructions(self): @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (a) - LOAD_NAME 1 (b) - %s - RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_NAME 1 (b) + %s + RETURN_VALUE """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) @@ -1135,12 +1135,12 @@ def test_binary_specialize(self): self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)") binary_subscr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (a) - LOAD_CONST 0 (0) - %s - RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_CONST 0 (0) + %s + RETURN_VALUE """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) @@ -1156,11 +1156,11 @@ def test_binary_specialize(self): @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_CONST 0 ('a') - LOAD_ATTR_SLOT 0 (__class__) - RETURN_VALUE + 1 LOAD_CONST 0 ('a') + LOAD_ATTR_SLOT 0 (__class__) + RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1171,13 +1171,13 @@ def test_load_attr_specialize(self): @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (str) - PUSH_NULL - LOAD_CONST 0 (1) - CALL_STR_1 1 - RETURN_VALUE + 1 LOAD_NAME 0 (str) + PUSH_NULL + LOAD_CONST 0 (1) + CALL_STR_1 1 + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1930,7 +1930,7 @@ def test_jump_target(self): def test_argval_argrepr(self): def f(*args): return dis.Instruction._get_argval_argrepr( - *args, labels_map={24: 1}, label_width=1) + *args, labels_map={24: 1}) offset = 42 co_consts = (0, 1, 2, 3) From a7de18cf32ce6c1eac55bb14826542a769ef537e Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 15:39:20 +0000 Subject: [PATCH 16/24] fix doctest --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 8bdb0efd806990..32429d0b8428b1 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -62,12 +62,12 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 - 3 LOAD_GLOBAL 1 (len + NULL) - LOAD_FAST 0 (alist) - CALL 1 - RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + RETURN_VALUE (The "2" is a line number). From cc24af88f35d6789d86bf360229db9a8c64188a2 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 16:06:32 +0000 Subject: [PATCH 17/24] whitespace --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 32429d0b8428b1..e50893bf95d07d 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -62,12 +62,12 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 - 3 LOAD_GLOBAL 1 (len + NULL) - LOAD_FAST 0 (alist) - CALL 1 - RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + RETURN_VALUE (The "2" is a line number). From 6542b06a7fbf4e283fa1cd1ae3fe25a57125cef3 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 16:33:38 +0000 Subject: [PATCH 18/24] whitespace --- Doc/library/dis.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index e50893bf95d07d..d0088c10ad5040 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -62,9 +62,9 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 - 3 LOAD_GLOBAL 1 (len + NULL) + 3 LOAD_GLOBAL 1 (len + NULL) LOAD_FAST 0 (alist) CALL 1 RETURN_VALUE From 823b0e1f9e4d2ff122528f75ccb9b41ed2ad34dd Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 16:48:40 +0000 Subject: [PATCH 19/24] add test with offsets --- Lib/test/test_dis.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index d0d454fa42bac3..0e7c59c5797f6c 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -112,6 +112,19 @@ def _f(a): _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) +dis_f_with_offsets = """\ +%3d 0 RESUME 0 + +%3d 2 LOAD_GLOBAL 1 (print + NULL) + 12 LOAD_FAST 0 (a) + 14 CALL 1 + 22 POP_TOP + +%3d 24 RETURN_CONST 1 (1) +""" % (_f.__code__.co_firstlineno, + _f.__code__.co_firstlineno + 1, + _f.__code__.co_firstlineno + 2) + dis_f_co_code = """\ RESUME 0 @@ -122,7 +135,6 @@ def _f(a): RETURN_CONST 1 """ - def bug708901(): for res in range(1, 10): @@ -899,15 +911,15 @@ def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs): def get_disassemble_as_string(self, func, lasti=-1): return self.get_disassembly(func, lasti, False) - def do_disassembly_test(self, func, expected): + def do_disassembly_test(self, func, expected, **kwargs): self.maxDiff = None - got = self.get_disassembly(func, depth=0) + got = self.get_disassembly(func, depth=0, **kwargs) self.do_disassembly_compare(got, expected) # Add checks for dis.disco if hasattr(func, '__code__'): got_disco = io.StringIO() with contextlib.redirect_stdout(got_disco): - dis.disco(func.__code__) + dis.disco(func.__code__, **kwargs) self.do_disassembly_compare(got_disco.getvalue(), expected) def test_opmap(self): @@ -936,6 +948,9 @@ def test_widths(self): def test_dis(self): self.do_disassembly_test(_f, dis_f) + def test_dis_with_offsets(self): + self.do_disassembly_test(_f, dis_f_with_offsets, show_offsets=True) + def test_bug_708901(self): self.do_disassembly_test(bug708901, dis_bug708901) From 2219a9661b960a03e0a6e09c9c4acc67e02b784d Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 17:04:54 +0000 Subject: [PATCH 20/24] add doc --- Doc/library/dis.rst | 27 +++++++++++++++++++++++---- Doc/whatsnew/3.13.rst | 2 ++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index d0088c10ad5040..480b5e3484b940 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -51,6 +51,12 @@ interpreter. transparent for forward jumps but needs to be taken into account when reasoning about backward jumps. + .. versionchanged:: 3.13 + The output shows logical labels rather than instruction offsets + for jump targets and exception handlers. The ``-O`` command line + option and the ``show_offsets`` argument were added to add the + instruction offsets to the output as well. + Example: Given the function :func:`!myfunc`:: def myfunc(alist): @@ -80,7 +86,7 @@ The :mod:`dis` module can be invoked as a script from the command line: .. code-block:: sh - python -m dis [-h] [-C] [infile] + python -m dis [-h] [-C] [-O] [infile] The following options are accepted: @@ -94,6 +100,10 @@ The following options are accepted: Show inline caches. +.. cmdoption:: -O, --show-offsets + + Show offsets of instructions. + If :file:`infile` is specified, its disassembled code will be written to stdout. Otherwise, disassembly is performed on compiled source code recieved from stdin. @@ -107,7 +117,7 @@ The bytecode analysis API allows pieces of Python code to be wrapped in a code. .. class:: Bytecode(x, *, first_line=None, current_offset=None,\ - show_caches=False, adaptive=False) + show_caches=False, adaptive=False, show_offsets=False) Analyse the bytecode corresponding to a function, generator, asynchronous generator, coroutine, method, string of source code, or a code object (as @@ -132,6 +142,9 @@ code. If *adaptive* is ``True``, :meth:`.dis` will display specialized bytecode that may be different from the original bytecode. + If *show_offsets* is ``True``, :meth:`.dis` will include instruction + offsets in the output. + .. classmethod:: from_traceback(tb, *, show_caches=False) Construct a :class:`Bytecode` instance from the given traceback, setting @@ -254,7 +267,8 @@ operation is being performed, so the intermediate analysis object isn't useful: Added the *show_caches* and *adaptive* parameters. -.. function:: distb(tb=None, *, file=None, show_caches=False, adaptive=False) +.. function:: distb(tb=None, *, file=None, show_caches=False, adaptive=False, + show_offset=False) Disassemble the top-of-stack function of a traceback, using the last traceback if none was passed. The instruction causing the exception is @@ -269,9 +283,12 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.11 Added the *show_caches* and *adaptive* parameters. + .. versionchanged:: 3.13 + Added the *show_offsets* parameter. .. function:: disassemble(code, lasti=-1, *, file=None, show_caches=False, adaptive=False) - disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False) + disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False, + show_offsets=False) Disassemble a code object, indicating the last instruction if *lasti* was provided. The output is divided in the following columns: @@ -296,6 +313,8 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.11 Added the *show_caches* and *adaptive* parameters. + .. versionchanged:: 3.13 + Added the *show_offsets* parameter. .. function:: get_instructions(x, *, first_line=None, show_caches=False, adaptive=False) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index ef5bdf6b845797..7b3b6a2b9a909b 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -173,6 +173,8 @@ dis * Change the output of :mod:`dis` module functions to show logical labels for jump targets and exception handlers, rather than offsets. + The offsets can be added with the new ``-O`` command line option or + the ``show_offsets`` parameter. (Contributed by Irit Katriel in :gh:`112137`.) dbm From f52d698569256795e3b396cdaaa59d52045d6407 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 17:09:00 +0000 Subject: [PATCH 21/24] whitespace --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 480b5e3484b940..cb839402397b11 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -68,12 +68,12 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 - 3 LOAD_GLOBAL 1 (len + NULL) - LOAD_FAST 0 (alist) - CALL 1 - RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + RETURN_VALUE (The "2" is a line number). From 278aae3c7fb180671f95de9d0e9564108b373505 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 22 Nov 2023 17:32:28 +0000 Subject: [PATCH 22/24] whitespace --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index cb839402397b11..dd68ddb7f94187 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -68,12 +68,12 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 RESUME 0 + 2 RESUME 0 - 3 LOAD_GLOBAL 1 (len + NULL) - LOAD_FAST 0 (alist) - CALL 1 - RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + RETURN_VALUE (The "2" is a line number). From 5420f6b7d71ae92b26e48a269ae96a15212f4c0a Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:06:02 +0000 Subject: [PATCH 23/24] tweak doc --- Doc/library/dis.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index dd68ddb7f94187..7e97f1a4524554 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -54,8 +54,7 @@ interpreter. .. versionchanged:: 3.13 The output shows logical labels rather than instruction offsets for jump targets and exception handlers. The ``-O`` command line - option and the ``show_offsets`` argument were added to add the - instruction offsets to the output as well. + option and the ``show_offsets`` argument were added. Example: Given the function :func:`!myfunc`:: From d741666769c42980e5a6731716cf997b56e30eb4 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 22 Nov 2023 22:03:12 +0000 Subject: [PATCH 24/24] remove extra line --- Lib/dis.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/dis.py b/Lib/dis.py index 0475888c6d8146..c05b8e0dd8617a 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -473,7 +473,6 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=0): *offset_width* sets the width of the instruction offset field """ fields = [] - # # Column: Source code line number if lineno_width: if self.starts_line: