rocky / python-xdis

Python cross-version bytecode library and disassembler
GNU General Public License v2.0
292 stars 95 forks source link

3.12 and 3.11 cross-version improvements #126

Closed 2elli closed 1 year ago

2elli commented 1 year ago

3.12

3.11 and 3.12 cross-version improvements

2elli commented 1 year ago

Looks like some of opcode_311 was overwritten when merging. Re-added that section, should be fixed up now.

rocky commented 1 year ago

Many thanks for fixing this up. I am sorry about the merge conflicts. In the future, to avoid this it would be best to put in a PR which can be marked as a draft.

2elli commented 1 year ago

Many thanks for fixing this up. I am sorry about the merge conflicts. In the future, to avoid this it would be best to put in a PR which can be marked as a draft.

Will do, thanks much.

rocky commented 1 year ago

FYI. Recently I fixed up the stack-effect test so it runs regularly now. And I corrected the 3.11 stack effect problems.

We apparently need to to the same for 3.12:

============================= test session starts ==============================
platform linux -- Python 3.12.0, pytest-7.4.2, pluggy-1.3.0
rootdir: /home/rocky/src/external-vcs/github/rocky/python-xdis
collected 2 items                                                              

pytest/test_stack_effect.py .F                                           [100%]

=================================== FAILURES ===================================
___________________________ test_stack_effect_vs_dis ___________________________

    @pytest.mark.skipif(
        xdis.PYTHON_VERSION_TRIPLE < (3, 4) or xdis.IS_PYPY,
        reason="Python version is before 3.4. Can't test",
    )
    def test_stack_effect_vs_dis():
        import dis

        def test_one(xdis_args, dis_args, has_arg):
            effect = xstack_effect(*xdis_args)
            check_effect = dis.stack_effect(*dis_args[:2])
            assert (
                effect != -100
            ), "%d (%s) needs adjusting; should be: should have effect %d" % (
                opcode,
                opname,
                check_effect,
            )
            if has_arg:
                op_val = "with operand %d" % dis_args[1]
            else:
                op_val = ""

            assert check_effect == effect, "%d (%s) %s not okay; effect %d vs %d" % (
                opcode,
                opname,
                op_val,
                effect,
                check_effect,
            )
            print("%d (%s) is good: effect %d" % (opcode, opname, effect))

        if xdis.IS_PYPY:
            variant = "pypy"
        else:
            variant = ""
        opc = get_opcode_module(None, variant)
        for (
            opname,
            opcode,
        ) in opc.opmap.items():
            if opname in ("EXTENDED_ARG", "NOP"):
                continue
            xdis_args = [opcode, opc]
            dis_args = [opcode]

            # TODO: if opcode takes an argument, we should vary the arg and try
            # values in addition to 0 as done below.
            if op_has_argument(opcode, opc):
                xdis_args.append(0)
                dis_args.append(0)
                has_arg = True
            else:
                has_arg = False

            if (
                xdis.PYTHON_VERSION_TRIPLE >= (3, 7)
                and opcode in opc.CONDITION_OPS
                and opname
                not in (
                    "JUMP_IF_FALSE_OR_POP",
                    "JUMP_IF_TRUE_OR_POP",
                    "POP_JUMP_IF_FALSE",
                    "POP_JUMP_IF_TRUE",
                    "SETUP_FINALLY",
                )
            ):
                xdis_args.append(0)
                dis_args.append(0)

            if has_arg:
                for i in range(0, 3):
                    dis_args[1] = xdis_args[2] = i
>                   test_one(xdis_args, dis_args, has_arg)

pytest/test_stack_effect.py:160: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

xdis_args = [150, <module 'xdis.opcodes.opcode_312' from '/home/rocky/src/external-vcs/github/rocky/python-xdis/xdis/opcodes/opcode_312.py'>, 0]
dis_args = [150, 0], has_arg = True

    def test_one(xdis_args, dis_args, has_arg):
        effect = xstack_effect(*xdis_args)
        check_effect = dis.stack_effect(*dis_args[:2])
        assert (
            effect != -100
        ), "%d (%s) needs adjusting; should be: should have effect %d" % (
            opcode,
            opname,
            check_effect,
        )
        if has_arg:
            op_val = "with operand %d" % dis_args[1]
        else:
            op_val = ""

>       assert check_effect == effect, "%d (%s) %s not okay; effect %d vs %d" % (
            opcode,
            opname,
            op_val,
            effect,
            check_effect,
        )
E       AssertionError: 150 (YIELD_VALUE) with operand 0 not okay; effect 1 vs 0
E       assert 0 == 1

pytest/test_stack_effect.py:110: AssertionError
----------------------------- Captured stdout call -----------------------------
1 (POP_TOP) is good: effect -1
11 (UNARY_NEGATIVE) is good: effect 0
12 (UNARY_NOT) is good: effect 0
15 (UNARY_INVERT) is good: effect 0
25 (BINARY_SUBSCR) is good: effect -1
60 (STORE_SUBSCR) is good: effect -3
61 (DELETE_SUBSCR) is good: effect -2
68 (GET_ITER) is good: effect 0
71 (LOAD_BUILD_CLASS) is good: effect 1
83 (RETURN_VALUE) is good: effect -1
=========================== short test summary info ============================
FAILED pytest/test_stack_effect.py::test_stack_effect_vs_dis - AssertionError...
========================= 1 failed, 1 passed in 0.08s ==========================