From 1c12214db3880168c6daa7e1655a1fda4d95f2cc Mon Sep 17 00:00:00 2001 From: Quinntyx <70780971+Quinntyx@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:30:08 -0500 Subject: [PATCH 1/2] Fix LOAD_COMMON_CONSTANT argument values --- pytest/test_instructions.py | 34 ++++++++++++++++++++++++- xdis/bytecode.py | 2 ++ xdis/opcodes/opcode_3x/opcode_314.py | 2 ++ xdis/opcodes/opcode_3x/opcode_315.py | 38 ++++++++++++++++++---------- 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/pytest/test_instructions.py b/pytest/test_instructions.py index fde2f3b5..169df0e8 100644 --- a/pytest/test_instructions.py +++ b/pytest/test_instructions.py @@ -1,11 +1,43 @@ """xdis.bytecode testing""" +import dis import sys import pytest from xdis import IS_GRAAL, IS_PYPY from xdis.bytecode import Bytecode from xdis.op_imports import get_opcode_module -from xdis.version_info import PYTHON_VERSION_TRIPLE +from xdis.version_info import PYTHON_IMPLEMENTATION, PYTHON_VERSION_TRIPLE + + +@pytest.mark.skipif( + IS_PYPY or PYTHON_VERSION_TRIPLE[:2] not in ((3, 14), (3, 15)), + reason="LOAD_COMMON_CONSTANT is specific to CPython 3.14 and 3.15", +) +def test_load_common_constant_argval_matches_dis() -> None: + codes = [ + compile(source, "", "exec") + for source in ( + "assert False", + 'result = {"success": True, "failure": False}', + ) + ] + + native = [ + (inst.arg, inst.argval, inst.argrepr) + for code in codes + for inst in dis.get_instructions(code) + if inst.opname == "LOAD_COMMON_CONSTANT" + ] + cross = [ + (inst.arg, inst.argval, inst.argrepr) + for code in codes + for inst in Bytecode( + code, get_opcode_module(PYTHON_VERSION_TRIPLE, PYTHON_IMPLEMENTATION) + ) + if inst.opname == "LOAD_COMMON_CONSTANT" + ] + + assert cross == native def extended_arg_fn36() -> int: diff --git a/xdis/bytecode.py b/xdis/bytecode.py index 948b8c5b..ef4ca7a1 100644 --- a/xdis/bytecode.py +++ b/xdis/bytecode.py @@ -433,6 +433,8 @@ def get_logical_instruction_at_offset( ) if hasattr(opc, "opcode_arg_fmt") and opname in opc.opcode_arg_fmt: argrepr = opc.opcode_arg_fmt[opname](arg) + if hasattr(opc, "opcode_arg_val") and opname in opc.opcode_arg_val: + argval = opc.opcode_arg_val[opname](arg) else: if fixed_length_instructions: i += 1 diff --git a/xdis/opcodes/opcode_3x/opcode_314.py b/xdis/opcodes/opcode_3x/opcode_314.py index 5d510c33..823fda62 100644 --- a/xdis/opcodes/opcode_3x/opcode_314.py +++ b/xdis/opcodes/opcode_3x/opcode_314.py @@ -377,6 +377,8 @@ def format_LOAD_COMMON_CONSTANT_314(arg: int): **{"LOAD_COMMON_CONSTANT": format_LOAD_COMMON_CONSTANT_314}, } +opcode_arg_val = opcode_arg_val314 = {} + opcode_extended_fmt = opcode_extended_fmt314 = { **opcode_313.opcode_extended_fmt313, **{"BINARY_OP": extended_BINARY_OP_314}, diff --git a/xdis/opcodes/opcode_3x/opcode_315.py b/xdis/opcodes/opcode_3x/opcode_315.py index 0fd81e27..eef75b18 100644 --- a/xdis/opcodes/opcode_3x/opcode_315.py +++ b/xdis/opcodes/opcode_3x/opcode_315.py @@ -373,24 +373,29 @@ def extended_BINARY_OP_315(opc, instructions): _common_constants = ( - "AssertionError", - "NotImplementedError", - "tuple", - "all", - "any", - "list", - "set", - "None", # <--- There is your oparg 7! - '""', - "True", - "False", - "-1", - "frozenset", - "()", + AssertionError, + NotImplementedError, + tuple, + all, + any, + list, + set, + None, + "", + True, + False, + -1, + frozenset, + (), ) def format_LOAD_COMMON_CONSTANT_315(arg: int): + obj = _common_constants[arg] + return obj.__name__ if isinstance(obj, type) else repr(obj) + + +def resolve_LOAD_COMMON_CONSTANT_315(arg: int): return _common_constants[arg] @@ -400,6 +405,11 @@ def format_LOAD_COMMON_CONSTANT_315(arg: int): **{"LOAD_COMMON_CONSTANT": format_LOAD_COMMON_CONSTANT_315}, } +opcode_arg_val = opcode_arg_val315 = { + **opcode_314.opcode_arg_val314, + **{"LOAD_COMMON_CONSTANT": resolve_LOAD_COMMON_CONSTANT_315}, +} + opcode_extended_fmt = opcode_extended_fmt315 = { **opcode_314.opcode_extended_fmt314, **{"BINARY_OP": extended_BINARY_OP_315}, From 3d5d3d65c05675b2889d49a6463d6f1f24405636 Mon Sep 17 00:00:00 2001 From: Quinntyx <70780971+Quinntyx@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:39:03 -0500 Subject: [PATCH 2/2] Limit common constant resolver to Python 3.15 --- xdis/opcodes/opcode_3x/opcode_314.py | 2 -- xdis/opcodes/opcode_3x/opcode_315.py | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/xdis/opcodes/opcode_3x/opcode_314.py b/xdis/opcodes/opcode_3x/opcode_314.py index 823fda62..5d510c33 100644 --- a/xdis/opcodes/opcode_3x/opcode_314.py +++ b/xdis/opcodes/opcode_3x/opcode_314.py @@ -377,8 +377,6 @@ def format_LOAD_COMMON_CONSTANT_314(arg: int): **{"LOAD_COMMON_CONSTANT": format_LOAD_COMMON_CONSTANT_314}, } -opcode_arg_val = opcode_arg_val314 = {} - opcode_extended_fmt = opcode_extended_fmt314 = { **opcode_313.opcode_extended_fmt313, **{"BINARY_OP": extended_BINARY_OP_314}, diff --git a/xdis/opcodes/opcode_3x/opcode_315.py b/xdis/opcodes/opcode_3x/opcode_315.py index eef75b18..e9b64371 100644 --- a/xdis/opcodes/opcode_3x/opcode_315.py +++ b/xdis/opcodes/opcode_3x/opcode_315.py @@ -406,8 +406,7 @@ def resolve_LOAD_COMMON_CONSTANT_315(arg: int): } opcode_arg_val = opcode_arg_val315 = { - **opcode_314.opcode_arg_val314, - **{"LOAD_COMMON_CONSTANT": resolve_LOAD_COMMON_CONSTANT_315}, + "LOAD_COMMON_CONSTANT": resolve_LOAD_COMMON_CONSTANT_315, } opcode_extended_fmt = opcode_extended_fmt315 = {