Esempio n. 1
0
    def test_extended_arg_make_function(self):
        code_obj = get_code(
            """
            def foo(x: int, y: int):
                pass
        """
        )

        # without EXTENDED_ARG
        concrete = ConcreteBytecode.from_code(code_obj)
        func_code = concrete.consts[1]
        self.assertEqual(concrete.names, ["int", "foo"])
        self.assertEqual(concrete.consts, [("x", "y"), func_code, "foo", None])
        if WORDCODE:
            expected = [
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("BUILD_CONST_KEY_MAP", 2, lineno=1),
                ConcreteInstr("LOAD_CONST", 1, lineno=1),
                ConcreteInstr("LOAD_CONST", 2, lineno=1),
                ConcreteInstr("MAKE_FUNCTION", 4, lineno=1),
                ConcreteInstr("STORE_NAME", 1, lineno=1),
                ConcreteInstr("LOAD_CONST", 3, lineno=1),
                ConcreteInstr("RETURN_VALUE", lineno=1),
            ]
        else:
            expected = [
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 1, lineno=1),
                ConcreteInstr("LOAD_CONST", 2, lineno=1),
                ConcreteInstr("MAKE_FUNCTION", 3 << 16, lineno=1),
                ConcreteInstr("STORE_NAME", 1, lineno=1),
                ConcreteInstr("LOAD_CONST", 3, lineno=1),
                ConcreteInstr("RETURN_VALUE", lineno=1),
            ]
        self.assertListEqual(list(concrete), expected)

        # with EXTENDED_ARG
        concrete = ConcreteBytecode.from_code(code_obj, extended_arg=True)
        func_code = concrete.consts[1]
        self.assertEqual(concrete.names, ["int", "foo"])
        self.assertEqual(concrete.consts, [("x", "y"), func_code, "foo", None])
        if not WORDCODE:
            expected = [
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 1, lineno=1),
                ConcreteInstr("LOAD_CONST", 2, lineno=1),
                ConcreteInstr("EXTENDED_ARG", 3, lineno=1),
                ConcreteInstr("MAKE_FUNCTION", 0, lineno=1),
                ConcreteInstr("STORE_NAME", 1, lineno=1),
                ConcreteInstr("LOAD_CONST", 3, lineno=1),
                ConcreteInstr("RETURN_VALUE", lineno=1),
            ]
        self.assertListEqual(list(concrete), expected)
Esempio n. 2
0
    def test_cellvar_freevar(self):
        concrete = ConcreteBytecode()
        concrete.cellvars = ["cell"]
        concrete.freevars = ["free"]
        concrete.append(ConcreteInstr("LOAD_DEREF", 0))
        concrete.append(ConcreteInstr("LOAD_DEREF", 1))
        code = concrete.to_code()

        concrete = ConcreteBytecode.from_code(code)
        self.assertEqual(concrete.cellvars, ["cell"])
        self.assertEqual(concrete.freevars, ["free"])
        self.assertEqual(
            list(concrete),
            [
                ConcreteInstr("LOAD_DEREF", 0, lineno=1),
                ConcreteInstr("LOAD_DEREF", 1, lineno=1),
            ],
        )

        bytecode = concrete.to_bytecode()
        self.assertEqual(bytecode.cellvars, ["cell"])
        self.assertEqual(
            list(bytecode),
            [
                Instr("LOAD_DEREF", CellVar("cell"), lineno=1),
                Instr("LOAD_DEREF", FreeVar("free"), lineno=1),
            ],
        )
Esempio n. 3
0
    def test_legalize(self):
        concrete = ConcreteBytecode()
        concrete.first_lineno = 3
        concrete.consts = [7, 8, 9]
        concrete.names = ["x", "y", "z"]
        concrete.extend([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            ConcreteInstr("LOAD_CONST", 1, lineno=4),
            ConcreteInstr("STORE_NAME", 1),
            SetLineno(5),
            ConcreteInstr("LOAD_CONST", 2, lineno=6),
            ConcreteInstr("STORE_NAME", 2),
        ])

        concrete.legalize()
        self.assertListEqual(
            list(concrete),
            [
                ConcreteInstr("LOAD_CONST", 0, lineno=3),
                ConcreteInstr("STORE_NAME", 0, lineno=3),
                ConcreteInstr("LOAD_CONST", 1, lineno=4),
                ConcreteInstr("STORE_NAME", 1, lineno=4),
                ConcreteInstr("LOAD_CONST", 2, lineno=5),
                ConcreteInstr("STORE_NAME", 2, lineno=5),
            ],
        )
Esempio n. 4
0
    def test_to_code_lnotab(self):

        # We use an actual function for the simple case to
        # ensure we get lnotab right
        def f():
            #
            #
            x = 7  # noqa
            y = 8  # noqa
            z = 9  # noqa

        fl = f.__code__.co_firstlineno
        concrete = ConcreteBytecode()
        concrete.consts = [None, 7, 8, 9]
        concrete.varnames = ["x", "y", "z"]
        concrete.first_lineno = fl
        concrete.extend([
            SetLineno(fl + 3),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_FAST", 0),
            SetLineno(fl + 4),
            ConcreteInstr("LOAD_CONST", 2),
            ConcreteInstr("STORE_FAST", 1),
            SetLineno(fl + 5),
            ConcreteInstr("LOAD_CONST", 3),
            ConcreteInstr("STORE_FAST", 2),
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("RETURN_VALUE"),
        ])

        code = concrete.to_code()
        self.assertEqual(code.co_code, f.__code__.co_code)
        self.assertEqual(code.co_lnotab, f.__code__.co_lnotab)
        if sys.version_info >= (3, 10):
            self.assertEqual(code.co_linetable, f.__code__.co_linetable)
Esempio n. 5
0
    def test_setlineno(self):
        # x = 7
        # y = 8
        # z = 9
        concrete = ConcreteBytecode()
        concrete.consts = [7, 8, 9]
        concrete.names = ["x", "y", "z"]
        concrete.first_lineno = 3
        concrete.extend([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            SetLineno(4),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_NAME", 1),
            SetLineno(5),
            ConcreteInstr("LOAD_CONST", 2),
            ConcreteInstr("STORE_NAME", 2),
        ])

        code = concrete.to_bytecode()
        self.assertEqual(
            code,
            [
                Instr("LOAD_CONST", 7, lineno=3),
                Instr("STORE_NAME", "x", lineno=3),
                Instr("LOAD_CONST", 8, lineno=4),
                Instr("STORE_NAME", "y", lineno=4),
                Instr("LOAD_CONST", 9, lineno=5),
                Instr("STORE_NAME", "z", lineno=5),
            ],
        )
Esempio n. 6
0
    def test_to_bytecode_consts(self):
        # x = -0.0
        # x = +0.0
        #
        # code optimized by the CPython 3.6 peephole optimizer which emits
        # duplicated constants (0.0 is twice in consts).
        code = ConcreteBytecode()
        code.consts = [0.0, None, -0.0, 0.0]
        code.names = ["x", "y"]
        code.extend([
            ConcreteInstr("LOAD_CONST", 2, lineno=1),
            ConcreteInstr("STORE_NAME", 0, lineno=1),
            ConcreteInstr("LOAD_CONST", 3, lineno=2),
            ConcreteInstr("STORE_NAME", 1, lineno=2),
            ConcreteInstr("LOAD_CONST", 1, lineno=2),
            ConcreteInstr("RETURN_VALUE", lineno=2),
        ])

        code = code.to_bytecode().to_concrete_bytecode()
        # the conversion changes the constant order: the order comes from
        # the order of LOAD_CONST instructions
        self.assertEqual(code.consts, [-0.0, 0.0, None])
        code.names = ["x", "y"]
        self.assertListEqual(
            list(code),
            [
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("STORE_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 1, lineno=2),
                ConcreteInstr("STORE_NAME", 1, lineno=2),
                ConcreteInstr("LOAD_CONST", 2, lineno=2),
                ConcreteInstr("RETURN_VALUE", lineno=2),
            ],
        )
Esempio n. 7
0
    def test_to_code_lnotab(self):
        # x = 7
        # y = 8
        # z = 9
        concrete = ConcreteBytecode()
        concrete.consts = [7, 8, 9]
        concrete.names = ["x", "y", "z"]
        concrete.first_lineno = 3
        concrete.extend([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            SetLineno(4),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_NAME", 1),
            SetLineno(5),
            ConcreteInstr("LOAD_CONST", 2),
            ConcreteInstr("STORE_NAME", 2),
        ])

        code = concrete.to_code()
        if WORDCODE:
            expected = b"d\x00Z\x00d\x01Z\x01d\x02Z\x02"
        else:
            expected = (b"d\x00\x00"
                        b"Z\x00\x00"
                        b"d\x01\x00"
                        b"Z\x01\x00"
                        b"d\x02\x00"
                        b"Z\x02\x00")
        self.assertEqual(code.co_code, expected)
        self.assertEqual(code.co_firstlineno, 3)
        self.assertEqual(
            code.co_lnotab,
            b"\x04\x01\x04\x01" if WORDCODE else b"\x06\x01\x06\x01")
Esempio n. 8
0
    def test_extended_arg(self):
        # Create a code object from arbitrary bytecode
        co_code = b"\x90\x12\x904\x90\xabd\xcd" if WORDCODE else b"\x904\x12d\xcd\xab"
        code = get_code("x=1")
        args = (
            (code.co_argcount,)
            if sys.version_info < (3, 8)
            else (code.co_argcount, code.co_posonlyargcount)
        )
        args += (
            code.co_kwonlyargcount,
            code.co_nlocals,
            code.co_stacksize,
            code.co_flags,
            co_code,
            code.co_consts,
            code.co_names,
            code.co_varnames,
            code.co_filename,
            code.co_name,
            code.co_firstlineno,
            code.co_lnotab,
            code.co_freevars,
            code.co_cellvars,
        )

        code = types.CodeType(*args)

        # without EXTENDED_ARG opcode
        bytecode = ConcreteBytecode.from_code(code)
        self.assertListEqual(
            list(bytecode), [ConcreteInstr("LOAD_CONST", 0x1234ABCD, lineno=1)]
        )

        # with EXTENDED_ARG opcode
        bytecode = ConcreteBytecode.from_code(code, extended_arg=True)
        if WORDCODE:
            expected = [
                ConcreteInstr("EXTENDED_ARG", 0x12, lineno=1),
                ConcreteInstr("EXTENDED_ARG", 0x34, lineno=1),
                ConcreteInstr("EXTENDED_ARG", 0xAB, lineno=1),
                ConcreteInstr("LOAD_CONST", 0xCD, lineno=1),
            ]
        else:
            expected = [
                ConcreteInstr("EXTENDED_ARG", 0x1234, lineno=1),
                ConcreteInstr("LOAD_CONST", 0xABCD, lineno=1),
            ]
        self.assertListEqual(list(bytecode), expected)
Esempio n. 9
0
    def test_async_gen_no_flag_is_async_True(self):
        # Test inference when we request an async function

        # Force coroutine
        code = ConcreteBytecode()
        code.update_flags(is_async=True)
        self.assertTrue(bool(code.flags & CompilerFlags.COROUTINE))

        # Infer coroutine or async generator
        for i, expected in (
            ("YIELD_VALUE", CompilerFlags.ASYNC_GENERATOR),
            ("YIELD_FROM", CompilerFlags.COROUTINE),
        ):
            code = ConcreteBytecode()
            code.append(ConcreteInstr(i))
            code.update_flags(is_async=True)
            self.assertTrue(bool(code.flags & expected))
Esempio n. 10
0
    def test_extended_lnotab(self):
        # x = 7
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            SetLineno(1 + 128),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(1 + 129),
            ConcreteInstr("LOAD_CONST", 1),
            SetLineno(1),
            ConcreteInstr("STORE_NAME", 1),
        ])
        concrete.consts = [7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 1

        if sys.version_info >= (3, 6):
            code = concrete.to_code()
            expected = b"d\x00Z\x00d\x01Z\x01"
            self.assertEqual(code.co_code, expected)
            self.assertEqual(code.co_firstlineno, 1)
            self.assertEqual(code.co_lnotab,
                             b"\x00\x7f\x02\x01\x02\x01\x00\x80\x02\xff")
        else:
            with self.assertRaises(ValueError) as cm:
                code = concrete.to_code()
            self.assertEqual(
                str(cm.exception),
                "negative line number delta is not supported "
                "on Python < 3.6",
            )
Esempio n. 11
0
    def test_extended_arg_unpack_ex(self):
        def test():
            p = [1, 2, 3, 4, 5, 6]
            q, r, *s, t = p
            return q, r, s, t

        test.__code__ = ConcreteBytecode.from_code(
            test.__code__, extended_arg=True).to_code()
        self.assertEqual(test.__code__.co_stacksize, 6)
        self.assertEqual(test(), (1, 2, [3, 4, 5], 6))
Esempio n. 12
0
 def test_invalid_types(self):
     code = ConcreteBytecode()
     code.append(Label())
     with self.assertRaises(ValueError):
         list(code)
     with self.assertRaises(ValueError):
         code.legalize()
     with self.assertRaises(ValueError):
         ConcreteBytecode([Label()])
Esempio n. 13
0
    def test_freevar(self):
        concrete = ConcreteBytecode()
        concrete.freevars = ["x"]
        concrete.append(ConcreteInstr("LOAD_DEREF", 0))
        code = concrete.to_code()

        concrete = ConcreteBytecode.from_code(code)
        self.assertEqual(concrete.cellvars, [])
        self.assertEqual(concrete.freevars, ["x"])
        self.assertEqual(list(concrete), [ConcreteInstr("LOAD_DEREF", 0, lineno=1)])

        bytecode = concrete.to_bytecode()
        self.assertEqual(bytecode.cellvars, [])
        self.assertEqual(list(bytecode), [Instr("LOAD_DEREF", FreeVar("x"), lineno=1)])
Esempio n. 14
0
    def check(self, source, function=False):
        ref_code = get_code(source, function=function)

        code = ConcreteBytecode.from_code(ref_code).to_code()
        self.assertEqual(code, ref_code)

        code = Bytecode.from_code(ref_code).to_code()
        self.assertEqual(code, ref_code)

        bytecode = Bytecode.from_code(ref_code)
        blocks = ControlFlowGraph.from_bytecode(bytecode)
        code = blocks.to_bytecode().to_code()
        self.assertEqual(code, ref_code)
Esempio n. 15
0
 def test_copy(self):
     concrete = ConcreteBytecode()
     concrete.first_lineno = 3
     concrete.consts = [7, 8, 9]
     concrete.names = ["x", "y", "z"]
     concrete.extend([
         ConcreteInstr("LOAD_CONST", 0),
         ConcreteInstr("STORE_NAME", 0),
         SetLineno(4),
         ConcreteInstr("LOAD_CONST", 1),
         ConcreteInstr("STORE_NAME", 1),
         SetLineno(5),
         ConcreteInstr("LOAD_CONST", 2),
         ConcreteInstr("STORE_NAME", 2),
     ])
     self.assertEqual(concrete, concrete.copy())
Esempio n. 16
0
 def test_attr(self):
     code_obj = get_code("x = 5")
     code = ConcreteBytecode.from_code(code_obj)
     self.assertEqual(code.consts, [5, None])
     self.assertEqual(code.names, ["x"])
     self.assertEqual(code.varnames, [])
     self.assertEqual(code.freevars, [])
     self.assertListEqual(
         list(code),
         [
             ConcreteInstr("LOAD_CONST", 0, lineno=1),
             ConcreteInstr("STORE_NAME", 0, lineno=1),
             ConcreteInstr("LOAD_CONST", 1, lineno=1),
             ConcreteInstr("RETURN_VALUE", lineno=1),
         ],
     )
Esempio n. 17
0
    def test_explicit_stacksize(self):
        # Passing stacksize=... to ConcreteBytecode.to_code should result in a
        # code object with the specified stacksize.  We pass some silly values
        # and assert that they are honored.
        code_obj = get_code("print('%s' % (a,b,c))")
        original_stacksize = code_obj.co_stacksize
        concrete = ConcreteBytecode.from_code(code_obj)

        # First with something bigger than necessary.
        explicit_stacksize = original_stacksize + 42
        new_code_obj = concrete.to_code(stacksize=explicit_stacksize)
        self.assertEqual(new_code_obj.co_stacksize, explicit_stacksize)

        # Then with something bogus.  We probably don't want to advertise this
        # in the documentation.  If this fails then decide if it's for good
        # reason, and remove if so.
        explicit_stacksize = 0
        new_code_obj = concrete.to_code(stacksize=explicit_stacksize)
        self.assertEqual(new_code_obj.co_stacksize, explicit_stacksize)
Esempio n. 18
0
    def test_load_classderef(self):
        concrete = ConcreteBytecode()
        concrete.cellvars = ["__class__"]
        concrete.freevars = ["__class__"]
        concrete.extend([
            ConcreteInstr("LOAD_CLASSDEREF", 1),
            ConcreteInstr("STORE_DEREF", 1)
        ])

        bytecode = concrete.to_bytecode()
        self.assertEqual(bytecode.freevars, ["__class__"])
        self.assertEqual(bytecode.cellvars, ["__class__"])
        self.assertEqual(
            list(bytecode),
            [
                Instr("LOAD_CLASSDEREF", FreeVar("__class__"), lineno=1),
                Instr("STORE_DEREF", FreeVar("__class__"), lineno=1),
            ],
        )

        concrete = bytecode.to_concrete_bytecode()
        self.assertEqual(concrete.freevars, ["__class__"])
        self.assertEqual(concrete.cellvars, ["__class__"])
        self.assertEqual(
            list(concrete),
            [
                ConcreteInstr("LOAD_CLASSDEREF", 1, lineno=1),
                ConcreteInstr("STORE_DEREF", 1, lineno=1),
            ],
        )

        code = concrete.to_code()
        self.assertEqual(code.co_freevars, ("__class__", ))
        self.assertEqual(code.co_cellvars, ("__class__", ))
        self.assertEqual(
            code.co_code,
            b"\x94\x01\x89\x01",
        )
Esempio n. 19
0
    def test_negative_lnotab(self):
        # x = 7
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(2),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_NAME", 1),
        ])
        concrete.consts = [7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 5

        code = concrete.to_code()
        expected = b"d\x00Z\x00d\x01Z\x01"
        self.assertEqual(code.co_code, expected)
        self.assertEqual(code.co_firstlineno, 5)
        self.assertEqual(code.co_lnotab, b"\x04\xfd")
Esempio n. 20
0
    def test_extended_lnotab2(self):
        # x = 7
        # 200 blank lines
        # y = 8
        base_code = compile("x = 7" + "\n" * 200 + "y = 8", "", "exec")
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            SetLineno(201),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_NAME", 1),
            ConcreteInstr("LOAD_CONST", 2),
            ConcreteInstr("RETURN_VALUE"),
        ])
        concrete.consts = [None, 7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 1

        code = concrete.to_code()
        self.assertEqual(code.co_code, base_code.co_code)
        self.assertEqual(code.co_firstlineno, base_code.co_firstlineno)
        self.assertEqual(code.co_lnotab, base_code.co_lnotab)
        if sys.version_info >= (3, 10):
            self.assertEqual(code.co_linetable, base_code.co_linetable)
Esempio n. 21
0
    def test_extended_lnotab(self):
        # x = 7
        # 200 blank lines
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            SetLineno(1 + 128),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(1 + 129),
            ConcreteInstr("LOAD_CONST", 1),
            SetLineno(1),
            ConcreteInstr("STORE_NAME", 1),
        ])
        concrete.consts = [7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 1

        code = concrete.to_code()
        expected = b"d\x00Z\x00d\x01Z\x01"
        self.assertEqual(code.co_code, expected)
        self.assertEqual(code.co_firstlineno, 1)
        self.assertEqual(code.co_lnotab,
                         b"\x02\x7f\x00\x01\x02\x01\x02\x80\x00\xff")
Esempio n. 22
0
 def test_repr(self):
     r = repr(ConcreteBytecode())
     self.assertIn("ConcreteBytecode", r)
     self.assertIn("0", r)
def f(a, b):
    #    res = a + b
    return


def g(a, b):
    res = a + b if a < b else b + a
    r = 0
    for a in range(res):
        r += 1
    return r or 2


for x in (f, g):
    #get byte code for f
    dis(x)
    print(f.__code__.co_code)
    c = Bytecode.from_code(x.__code__)
    cc = ConcreteBytecode.from_code(x.__code__)
    dump_bytecode(c)
    dump_bytecode(cc)

    #generate byte code
    cnew = c.to_code()

    x.__code__ = cnew
    dis(x)

    print(x(3, 5))
Esempio n. 24
0
    def test_label3(self):
        """
        CPython generates useless EXTENDED_ARG 0 in some cases. We need to
        properly track them as otherwise we can end up with broken offset for
        jumps.
        """
        source = """
            def func(x):
                if x == 1:
                    return x + 0
                elif x == 2:
                    return x + 1
                elif x == 3:
                    return x + 2
                elif x == 4:
                    return x + 3
                elif x == 5:
                    return x + 4
                elif x == 6:
                    return x + 5
                elif x == 7:
                    return x + 6
                elif x == 8:
                    return x + 7
                elif x == 9:
                    return x + 8
                elif x == 10:
                    return x + 9
                elif x == 11:
                    return x + 10
                elif x == 12:
                    return x + 11
                elif x == 13:
                    return x + 12
                elif x == 14:
                    return x + 13
                elif x == 15:
                    return x + 14
                elif x == 16:
                    return x + 15
                elif x == 17:
                    return x + 16
                return -1
        """
        code = get_code(source, function=True)
        bcode = Bytecode.from_code(code)
        concrete = bcode.to_concrete_bytecode()
        self.assertIsInstance(concrete, ConcreteBytecode)

        # Ensure that we do not generate broken code
        loc = {}
        exec(textwrap.dedent(source), loc)
        func = loc["func"]
        func.__code__ = bcode.to_code()
        for i, x in enumerate(range(1, 18)):
            self.assertEqual(func(x), x + i)
        self.assertEqual(func(18), -1)

        # Ensure that we properly round trip in such cases
        self.assertEqual(
            ConcreteBytecode.from_code(code).to_code().co_code, code.co_code)
Esempio n. 25
0
    def test_expected_arg_with_many_consts(self):
        def test():
            var = 0
            var = 1
            var = 2
            var = 3
            var = 4
            var = 5
            var = 6
            var = 7
            var = 8
            var = 9
            var = 10
            var = 11
            var = 12
            var = 13
            var = 14
            var = 15
            var = 16
            var = 17
            var = 18
            var = 19
            var = 20
            var = 21
            var = 22
            var = 23
            var = 24
            var = 25
            var = 26
            var = 27
            var = 28
            var = 29
            var = 30
            var = 31
            var = 32
            var = 33
            var = 34
            var = 35
            var = 36
            var = 37
            var = 38
            var = 39
            var = 40
            var = 41
            var = 42
            var = 43
            var = 44
            var = 45
            var = 46
            var = 47
            var = 48
            var = 49
            var = 50
            var = 51
            var = 52
            var = 53
            var = 54
            var = 55
            var = 56
            var = 57
            var = 58
            var = 59
            var = 60
            var = 61
            var = 62
            var = 63
            var = 64
            var = 65
            var = 66
            var = 67
            var = 68
            var = 69
            var = 70
            var = 71
            var = 72
            var = 73
            var = 74
            var = 75
            var = 76
            var = 77
            var = 78
            var = 79
            var = 80
            var = 81
            var = 82
            var = 83
            var = 84
            var = 85
            var = 86
            var = 87
            var = 88
            var = 89
            var = 90
            var = 91
            var = 92
            var = 93
            var = 94
            var = 95
            var = 96
            var = 97
            var = 98
            var = 99
            var = 100
            var = 101
            var = 102
            var = 103
            var = 104
            var = 105
            var = 106
            var = 107
            var = 108
            var = 109
            var = 110
            var = 111
            var = 112
            var = 113
            var = 114
            var = 115
            var = 116
            var = 117
            var = 118
            var = 119
            var = 120
            var = 121
            var = 122
            var = 123
            var = 124
            var = 125
            var = 126
            var = 127
            var = 128
            var = 129
            var = 130
            var = 131
            var = 132
            var = 133
            var = 134
            var = 135
            var = 136
            var = 137
            var = 138
            var = 139
            var = 140
            var = 141
            var = 142
            var = 143
            var = 144
            var = 145
            var = 146
            var = 147
            var = 148
            var = 149
            var = 150
            var = 151
            var = 152
            var = 153
            var = 154
            var = 155
            var = 156
            var = 157
            var = 158
            var = 159
            var = 160
            var = 161
            var = 162
            var = 163
            var = 164
            var = 165
            var = 166
            var = 167
            var = 168
            var = 169
            var = 170
            var = 171
            var = 172
            var = 173
            var = 174
            var = 175
            var = 176
            var = 177
            var = 178
            var = 179
            var = 180
            var = 181
            var = 182
            var = 183
            var = 184
            var = 185
            var = 186
            var = 187
            var = 188
            var = 189
            var = 190
            var = 191
            var = 192
            var = 193
            var = 194
            var = 195
            var = 196
            var = 197
            var = 198
            var = 199
            var = 200
            var = 201
            var = 202
            var = 203
            var = 204
            var = 205
            var = 206
            var = 207
            var = 208
            var = 209
            var = 210
            var = 211
            var = 212
            var = 213
            var = 214
            var = 215
            var = 216
            var = 217
            var = 218
            var = 219
            var = 220
            var = 221
            var = 222
            var = 223
            var = 224
            var = 225
            var = 226
            var = 227
            var = 228
            var = 229
            var = 230
            var = 231
            var = 232
            var = 233
            var = 234
            var = 235
            var = 236
            var = 237
            var = 238
            var = 239
            var = 240
            var = 241
            var = 242
            var = 243
            var = 244
            var = 245
            var = 246
            var = 247
            var = 248
            var = 249
            var = 250
            var = 251
            var = 252
            var = 253
            var = 254
            var = 255
            var = 256
            var = 257
            var = 258
            var = 259

            return var

        test.__code__ = ConcreteBytecode.from_code(
            test.__code__, extended_arg=True).to_code()
        self.assertEqual(test.__code__.co_stacksize, 1)
        self.assertEqual(test(), 259)
Esempio n. 26
0
    def test_async_gen_no_flag_is_async_None(self):
        # Test inference in the absence of any flag set on the bytecode

        # Infer generator
        code = ConcreteBytecode()
        code.append(ConcreteInstr("YIELD_VALUE"))
        code.update_flags()
        self.assertTrue(bool(code.flags & CompilerFlags.GENERATOR))

        # Infer coroutine
        code = ConcreteBytecode()
        code.append(ConcreteInstr("GET_AWAITABLE"))
        code.update_flags()
        self.assertTrue(bool(code.flags & CompilerFlags.COROUTINE))

        # Infer coroutine or async generator
        for i, expected in (
            ("YIELD_VALUE", CompilerFlags.ASYNC_GENERATOR),
            ("YIELD_FROM", CompilerFlags.COROUTINE),
        ):
            code = ConcreteBytecode()
            code.append(ConcreteInstr("GET_AWAITABLE"))
            code.append(ConcreteInstr(i))
            code.update_flags()
            self.assertTrue(bool(code.flags & expected))
Esempio n. 27
0
    def test_extended_arg_make_function(self):
        if (3, 9) <= sys.version_info < (3, 10):
            from _pydevd_frame_eval.vendored.bytecode.tests.util_annotation import get_code as get_code_future

            code_obj = get_code_future("""
                def foo(x: int, y: int):
                    pass
                """)
        else:
            code_obj = get_code("""
                def foo(x: int, y: int):
                    pass
                """)

        # without EXTENDED_ARG
        concrete = ConcreteBytecode.from_code(code_obj)
        if sys.version_info >= (3, 10):
            func_code = concrete.consts[2]
            names = ["int", "foo"]
            consts = ["x", "y", func_code, "foo", None]
            const_offset = 1
            name_offset = 1
            first_instrs = [
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 1, lineno=1),
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("BUILD_TUPLE", 4, lineno=1),
            ]
        elif (sys.version_info >= (3, 7)
              and concrete.flags & CompilerFlags.FUTURE_ANNOTATIONS):
            func_code = concrete.consts[2]
            names = ["foo"]
            consts = ["int", ("x", "y"), func_code, "foo", None]
            const_offset = 1
            name_offset = 0
            first_instrs = [
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 0 + const_offset, lineno=1),
                ConcreteInstr("BUILD_CONST_KEY_MAP", 2, lineno=1),
            ]
        else:
            func_code = concrete.consts[1]
            names = ["int", "foo"]
            consts = [("x", "y"), func_code, "foo", None]
            const_offset = 0
            name_offset = 1
            first_instrs = [
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_NAME", 0, lineno=1),
                ConcreteInstr("LOAD_CONST", 0 + const_offset, lineno=1),
                ConcreteInstr("BUILD_CONST_KEY_MAP", 2, lineno=1),
            ]

        self.assertEqual(concrete.names, names)
        self.assertEqual(concrete.consts, consts)
        expected = first_instrs + [
            ConcreteInstr("LOAD_CONST", 1 + const_offset, lineno=1),
            ConcreteInstr("LOAD_CONST", 2 + const_offset, lineno=1),
            ConcreteInstr("MAKE_FUNCTION", 4, lineno=1),
            ConcreteInstr("STORE_NAME", name_offset, lineno=1),
            ConcreteInstr("LOAD_CONST", 3 + const_offset, lineno=1),
            ConcreteInstr("RETURN_VALUE", lineno=1),
        ]
        self.assertListEqual(list(concrete), expected)

        # with EXTENDED_ARG
        concrete = ConcreteBytecode.from_code(code_obj, extended_arg=True)
        # With future annotation the int annotation is stringified and
        # stored as constant this the default behavior under Python 3.10
        if sys.version_info >= (3, 10):
            func_code = concrete.consts[2]
            names = ["int", "foo"]
            consts = ["x", "y", func_code, "foo", None]
        elif concrete.flags & CompilerFlags.FUTURE_ANNOTATIONS:
            func_code = concrete.consts[2]
            names = ["foo"]
            consts = ["int", ("x", "y"), func_code, "foo", None]
        else:
            func_code = concrete.consts[1]
            names = ["int", "foo"]
            consts = [("x", "y"), func_code, "foo", None]

        self.assertEqual(concrete.names, names)
        self.assertEqual(concrete.consts, consts)
        self.assertListEqual(list(concrete), expected)
Esempio n. 28
0
    def test_eq(self):
        code = ConcreteBytecode()
        self.assertFalse(code == 1)

        for name, val in (
            ("names", ["a"]),
            ("varnames", ["a"]),
            ("consts", [1]),
            ("argcount", 1),
            ("kwonlyargcount", 2),
            ("flags", CompilerFlags(CompilerFlags.GENERATOR)),
            ("first_lineno", 10),
            ("filename", "xxxx.py"),
            ("name", "__x"),
            ("docstring", "x-x-x"),
            ("cellvars", [CellVar("x")]),
            ("freevars", [FreeVar("x")]),
        ):
            c = ConcreteBytecode()
            setattr(c, name, val)
            # For obscure reasons using assertNotEqual here fail
            self.assertFalse(code == c)

        if sys.version_info > (3, 8):
            c = ConcreteBytecode()
            c.posonlyargcount = 10
            self.assertFalse(code == c)

        c = ConcreteBytecode()
        c.consts = [1]
        code.consts = [1]
        c.append(ConcreteInstr("LOAD_CONST", 0))
        self.assertFalse(code == c)
Esempio n. 29
0
        def test_fail_extended_arg_jump(self):
            def test():
                var = None
                for _ in range(0, 1):
                    var = 0
                    var = 1
                    var = 2
                    var = 3
                    var = 4
                    var = 5
                    var = 6
                    var = 7
                    var = 8
                    var = 9
                    var = 10
                    var = 11
                    var = 12
                    var = 13
                    var = 14
                    var = 15
                    var = 16
                    var = 17
                    var = 18
                    var = 19
                    var = 20
                    var = 21
                    var = 22
                    var = 23
                    var = 24
                    var = 25
                    var = 26
                    var = 27
                    var = 28
                    var = 29
                    var = 30
                    var = 31
                    var = 32
                    var = 33
                    var = 34
                    var = 35
                    var = 36
                    var = 37
                    var = 38
                    var = 39
                    var = 40
                    var = 41
                    var = 42
                    var = 43
                    var = 44
                    var = 45
                    var = 46
                    var = 47
                    var = 48
                    var = 49
                    var = 50
                    var = 51
                    var = 52
                    var = 53
                    var = 54
                    var = 55
                    var = 56
                    var = 57
                    var = 58
                    var = 59
                    var = 60
                    var = 61
                    var = 62
                    var = 63
                    var = 64
                    var = 65
                    var = 66
                    var = 67
                    var = 68
                    var = 69
                    var = 70
                return var

            # Generate the bytecode with extended arguments
            bytecode = ConcreteBytecode.from_code(test.__code__,
                                                  extended_arg=True)
            bytecode.to_code()
Esempio n. 30
0
    def test_async_gen_flags(self):
        # Test inference in the presence of pre-existing flags

        for is_async in (None, True):

            # Infer generator
            code = ConcreteBytecode()
            code.append(ConcreteInstr("YIELD_VALUE"))
            for f, expected in (
                (CompilerFlags.COROUTINE, CompilerFlags.ASYNC_GENERATOR),
                (CompilerFlags.ASYNC_GENERATOR, CompilerFlags.ASYNC_GENERATOR),
                (CompilerFlags.ITERABLE_COROUTINE,
                 CompilerFlags.ITERABLE_COROUTINE),
            ):
                code.flags = CompilerFlags(f)
                code.update_flags(is_async=is_async)
                self.assertTrue(bool(code.flags & expected))

            # Infer coroutine
            code = ConcreteBytecode()
            code.append(ConcreteInstr("YIELD_FROM"))
            for f, expected in (
                (CompilerFlags.COROUTINE, CompilerFlags.COROUTINE),
                (CompilerFlags.ASYNC_GENERATOR, CompilerFlags.COROUTINE),
                (CompilerFlags.ITERABLE_COROUTINE,
                 CompilerFlags.ITERABLE_COROUTINE),
            ):
                code.flags = CompilerFlags(f)
                code.update_flags(is_async=is_async)
                self.assertTrue(bool(code.flags & expected))

            # Crash on ITERABLE_COROUTINE with async bytecode
            code = ConcreteBytecode()
            code.append(ConcreteInstr("GET_AWAITABLE"))
            code.flags = CompilerFlags(CompilerFlags.ITERABLE_COROUTINE)
            with self.assertRaises(ValueError):
                code.update_flags(is_async=is_async)