Skip to content

dis._unpack_opargs should handle EXTENDED_ARG_QUICK #92932

@colesbury

Description

@colesbury

In Python 3.11b0, dis.dis() and dis.get_instructions() will show the "wrong" operand values for instructions prefixed by EXTENDED_ARG_QUICK.

cpython/Lib/dis.py

Lines 591 to 595 in a4460f2

deop = _deoptop(op)
caches = _inline_cache_entries[deop]
if deop >= HAVE_ARGUMENT:
arg = code[i+1] | extended_arg
extended_arg = (arg << 8) if op == EXTENDED_ARG else 0

The bug is that this line only checks for EXTENDED_ARG instructions. It should check for instructions that deoptimize to EXTENDED_ARG (i.e. deop == EXTENDED_ARG).

extended_arg = (arg << 8) if op == EXTENDED_ARG else 0

To reproduce the issue, consider this snippet adapted from cloudpickle:

import random
import textwrap
import dis

nvars = 65537 + 258
names = ['g%d' % i for i in range(1, nvars)]
r = random.Random(42)
d = {name: r.randrange(100) for name in names}
# def f(x):
#     x = g1, g2, ...
code = """
def f():
    x = {tup}
""".format(tup=', '.join(names))
exec(textwrap.dedent(code), d, d)
f = d['f']

dis.dis(f)

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixesstdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      close