Home - Summaries: (main) : (py3.11) : Everything - Nightly builds - Benchmarks - RPython - Builders - About

pypy/interpreter/astcompiler/test/apptest_patma.py::test_match_mapping_codegen_uses_unpack_sequence

def test_match_mapping_codegen_uses_unpack_sequence():
        """MATCH_KEYS result should be unpacked with UNPACK_SEQUENCE, not
        with DUP_TOP+BINARY_SUBSCR+rotation.  CPython emits:
          MATCH_KEYS / COPY 1 / POP_JUMP_FORWARD_IF_NONE / UNPACK_SEQUENCE n
        PyPy must match that pattern to avoid emitting SWAP instructions."""
        import dis
    
        def f(x):
            match x:
                case {'a': a, 'b': b, 'c': _}:
                    return a, b
    
>       instrs = list(dis.get_instructions(f))

interpreter/astcompiler/test/apptest_patma.py:372: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

code = W_BytesObject('|\x00\x1f\x00r\x19\x1e\x00d\x01k\x05r\x19d\x02!\x00&\x01d\x00u\...x01\x00\x01\x00\x01\x00|\x01|\x02f\x02S\x00\x01\x00\x01\x00\x01\x00d\x00S\x00')
varname_from_oparg = bound method _varname_from_oparg, names = W_TupleObject()
co_consts = W_TupleObject(<pypy.objspace.std.noneobject.W_NoneObject object at 0x7efffe5b9..._TupleObject(W_UnicodeObject('a'), W_UnicodeObject('b'), W_UnicodeObject('c')))
linestarts = W_DictObject(<pypy.objspace.std.dictmultiobject.IntDictStrategy object at 0x7efffda17150>)
line_offset = W_IntObject(0), exception_entries = W_TupleObject()
co_positions = <pypy.objspace.std.iterobject.W_FastListIterObject object at 0x7efff8cda810>
show_caches = W_BoolObject(False)

    def _get_instructions_bytes(code, varname_from_oparg=None,
                                names=None, co_consts=None,
                                linestarts=None, line_offset=0,
                                exception_entries=(), co_positions=None,
                                show_caches=False):
        """Iterate over the instructions in a bytecode string.
    
        Generates a sequence of Instruction namedtuples giving the details of each
        opcode.  Additional information about the code's runtime environment
        (e.g. variable names, co_consts) can be specified using optional
        arguments.
    
        """
        co_positions = co_positions or iter(())
        get_name = None if names is None else names.__getitem__
        labels = set(findlabels(code))
        for start, end, target, _, _ in exception_entries:
            for i in range(start, end):
                labels.add(target)
        starts_line = None
        for offset, op, arg in _unpack_opargs(code):
            if linestarts is not None:
                starts_line = linestarts.get(offset, None)
                if starts_line is not None:
                    starts_line += line_offset
            is_jump_target = offset in labels
            argval = None
            argrepr = ''
            positions = Positions(*next(co_positions, ()))
            deop = _deoptop(op)
            caches = _inline_cache_entries[deop]
            if arg is not None:
                #  Set argval to the dereferenced value of the argument when
                #  available, and argrepr to the string representation of argval.
                #    _disassemble_bytes needs the string repr of the
                #    raw name index for LOAD_GLOBAL, LOAD_CONST, etc.
                argval = arg
                if deop in hasconst:
                    argval, argrepr = _get_const_info(deop, arg, co_consts)
                elif deop in hasname:
                    if deop == LOAD_GLOBAL:
                        argval, argrepr = _get_name_info(arg//2, get_name)
                        if (arg & 1) and argrepr:
                            argrepr = "NULL + " + argrepr
                    elif deop == LOAD_ATTR:
                        argval, argrepr = _get_name_info(arg//2, get_name)
                        if (arg & 1) and argrepr:
                            argrepr = "NULL|self + " + argrepr
                    elif deop == LOAD_SUPER_ATTR:
                        argval, argrepr = _get_name_info(arg//4, get_name)
                        if (arg & 1) and argrepr:
                            argrepr = "NULL|self + " + argrepr
                    else:
                        argval, argrepr = _get_name_info(arg, get_name)
                elif deop in hasjabs:
                    argval = arg*2
                    argrepr = "to " + repr(argval)
                elif deop in hasjrel:
                    signed_arg = -arg if _is_backward_jump(deop) else arg
                    argval = offset + 2 + signed_arg*2
                    argval += 2 * caches
                    argrepr = "to " + repr(argval)
                elif deop in haslocal or deop in hasfree:
                    argval, argrepr = _get_name_info(arg, varname_from_oparg)
                elif deop in hascompare:
                    argval = cmp_op[arg>>4]
                    argrepr = argval
                elif deop == FORMAT_VALUE:
                    argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3]
                    argval = (argval, bool(arg & 0x4))
                    if argval[1]:
                        if argrepr:
                            argrepr += ', '
                        argrepr += 'with format'
                elif deop == MAKE_FUNCTION:
                    argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS)
                                        if arg & (1<<i))
>               elif deop == BINARY_OP:
E               (application-level) NameError: name 'BINARY_OP' is not defined

../lib-python/3/dis.py:512: NameError
builder: own-linux-x86-64 build #10877+
test: pypy/interpreter/astcompiler/test/apptest_patma.py::test_match_mapping_codegen_uses_unpack_sequence