Beispiel #1
0
    def test_get_jump_target(self):
        jump_abs = ConcreteInstr("JUMP_ABSOLUTE", 3)
        self.assertEqual(jump_abs.get_jump_target(100), 3)

        jump_forward = ConcreteInstr("JUMP_FORWARD", 5)
        self.assertEqual(jump_forward.get_jump_target(10),
                         17 if WORDCODE else 18)
Beispiel #2
0
    def test_label2(self):
        bytecode = Bytecode()
        label = Label()
        bytecode.extend([
            Instr("LOAD_NAME", "test", lineno=1),
            Instr("POP_JUMP_IF_FALSE", label),
            Instr("LOAD_CONST", 5, lineno=2),
            Instr("STORE_NAME", "x"),
            Instr("JUMP_FORWARD", label),
            Instr("LOAD_CONST", 7, lineno=4),
            Instr("STORE_NAME", "x"),
            label,
            Instr("LOAD_CONST", None),
            Instr("RETURN_VALUE"),
        ])

        concrete = bytecode.to_concrete_bytecode()
        expected = [
            ConcreteInstr("LOAD_NAME", 0, lineno=1),
            ConcreteInstr("POP_JUMP_IF_FALSE",
                          14 if WORDCODE else 21,
                          lineno=1),
            ConcreteInstr("LOAD_CONST", 0, lineno=2),
            ConcreteInstr("STORE_NAME", 1, lineno=2),
            ConcreteInstr("JUMP_FORWARD", 4 if WORDCODE else 6, lineno=2),
            ConcreteInstr("LOAD_CONST", 1, lineno=4),
            ConcreteInstr("STORE_NAME", 1, lineno=4),
            ConcreteInstr("LOAD_CONST", 2, lineno=4),
            ConcreteInstr("RETURN_VALUE", lineno=4),
        ]
        self.assertListEqual(list(concrete), expected)
        self.assertListEqual(concrete.consts, [5, 7, None])
        self.assertListEqual(concrete.names, ["test", "x"])
        self.assertListEqual(concrete.varnames, [])
Beispiel #3
0
    def test_label2(self):
        bytecode = Bytecode()
        label = Label()
        bytecode.extend([
            Instr('LOAD_NAME', 'test', lineno=1),
            Instr('POP_JUMP_IF_FALSE', label),
            Instr('LOAD_CONST', 5, lineno=2),
            Instr('STORE_NAME', 'x'),
            Instr('JUMP_FORWARD', label),
            Instr('LOAD_CONST', 7, lineno=4),
            Instr('STORE_NAME', 'x'), label,
            Instr('LOAD_CONST', None),
            Instr('RETURN_VALUE')
        ])

        concrete = bytecode.to_concrete_bytecode()
        expected = [
            ConcreteInstr('LOAD_NAME', 0, lineno=1),
            ConcreteInstr('POP_JUMP_IF_FALSE',
                          14 if WORDCODE else 21,
                          lineno=1),
            ConcreteInstr('LOAD_CONST', 0, lineno=2),
            ConcreteInstr('STORE_NAME', 1, lineno=2),
            ConcreteInstr('JUMP_FORWARD', 4 if WORDCODE else 6, lineno=2),
            ConcreteInstr('LOAD_CONST', 1, lineno=4),
            ConcreteInstr('STORE_NAME', 1, lineno=4),
            ConcreteInstr('LOAD_CONST', 2, lineno=4),
            ConcreteInstr('RETURN_VALUE', lineno=4)
        ]
        self.assertListEqual(list(concrete), expected)
        self.assertListEqual(concrete.consts, [5, 7, None])
        self.assertListEqual(concrete.names, ['test', 'x'])
        self.assertListEqual(concrete.varnames, [])
Beispiel #4
0
    def test_constructor(self):
        with self.assertRaises(ValueError):
            # need an argument
            ConcreteInstr("LOAD_CONST")
        with self.assertRaises(ValueError):
            # must not have an argument
            ConcreteInstr("ROT_TWO", 33)

        # invalid argument
        with self.assertRaises(TypeError):
            ConcreteInstr("LOAD_CONST", 1.0)
        with self.assertRaises(ValueError):
            ConcreteInstr("LOAD_CONST", -1)
        with self.assertRaises(TypeError):
            ConcreteInstr("LOAD_CONST", 5, lineno=1.0)
        with self.assertRaises(ValueError):
            ConcreteInstr("LOAD_CONST", 5, lineno=-1)

        # test maximum argument
        with self.assertRaises(ValueError):
            ConcreteInstr("LOAD_CONST", 2147483647 + 1)
        instr = ConcreteInstr("LOAD_CONST", 2147483647)
        self.assertEqual(instr.arg, 2147483647)

        # test meaningless extended args
        instr = ConcreteInstr('LOAD_FAST', 8, lineno=3, extended_args=1)
        self.assertEqual(instr.name, 'LOAD_FAST')
        self.assertEqual(instr.arg, 8)
        self.assertEqual(instr.lineno, 3)
        self.assertEqual(instr.size, 4)
Beispiel #5
0
    def test_flag_inference(self):

        # Check no loss of non-infered flags
        code = ControlFlowGraph()
        code.flags |= (CompilerFlags.NEWLOCALS | CompilerFlags.VARARGS
                       | CompilerFlags.VARKEYWORDS | CompilerFlags.NESTED
                       | CompilerFlags.FUTURE_GENERATOR_STOP)
        code.update_flags()
        for f in (CompilerFlags.NEWLOCALS, CompilerFlags.VARARGS,
                  CompilerFlags.VARKEYWORDS, CompilerFlags.NESTED,
                  CompilerFlags.NOFREE, CompilerFlags.OPTIMIZED,
                  CompilerFlags.FUTURE_GENERATOR_STOP):
            self.assertTrue(bool(code.flags & f))

        # Infer optimized and nofree
        code = Bytecode()
        flags = infer_flags(code)
        self.assertTrue(bool(flags & CompilerFlags.OPTIMIZED))
        self.assertTrue(bool(flags & CompilerFlags.NOFREE))
        code.append(ConcreteInstr('STORE_NAME', 1))
        flags = infer_flags(code)
        self.assertFalse(bool(flags & CompilerFlags.OPTIMIZED))
        self.assertTrue(bool(flags & CompilerFlags.NOFREE))
        code.append(ConcreteInstr('STORE_DEREF', 2))
        code.update_flags()
        self.assertFalse(bool(code.flags & CompilerFlags.OPTIMIZED))
        self.assertFalse(bool(code.flags & CompilerFlags.NOFREE))

        # Infer generator
        code = ConcreteBytecode()
        code.append(ConcreteInstr('YIELD_VALUE'))
        for is_async, expected in ((False, CompilerFlags.GENERATOR),
                                   (True, CompilerFlags.ASYNC_GENERATOR)):
            self.assertTrue(bool(infer_flags(code, is_async) & expected))

        # Infer coroutine
        code = ConcreteBytecode()
        code.append(ConcreteInstr('GET_AWAITABLE'))
        iter_flags = CompilerFlags(CompilerFlags.ITERABLE_COROUTINE)
        for f, expected in ((CompilerFlags(0), True), (iter_flags, False)):
            code.flags = f
            self.assertEqual(bool(infer_flags(code) & CompilerFlags.COROUTINE),
                             expected)

        # Test check flag sanity
        code.append(ConcreteInstr('YIELD_VALUE'))
        code.flags = CompilerFlags(CompilerFlags.GENERATOR
                                   | CompilerFlags.COROUTINE)
        infer_flags(code, is_async=True)  # Just want to be sure it pases
        with self.assertRaises(ValueError):
            code.update_flags()

        with self.assertRaises(ValueError):
            infer_flags(None)
Beispiel #6
0
 def test_cellvars(self):
     code = Bytecode()
     code.cellvars = ['x']
     code.freevars = ['y']
     code.extend([Instr('LOAD_DEREF', CellVar('x'), lineno=1),
                  Instr('LOAD_DEREF', FreeVar('y'), lineno=1)])
     concrete = code.to_concrete_bytecode()
     self.assertEqual(concrete.cellvars, ['x'])
     self.assertEqual(concrete.freevars, ['y'])
     code.extend([ConcreteInstr("LOAD_DEREF", 0, lineno=1),
                  ConcreteInstr("LOAD_DEREF", 1, lineno=1)])
Beispiel #7
0
    def test_disassemble(self):
        instr = ConcreteInstr.disassemble(1, b'\td\x03\x00', 0)
        self.assertEqual(instr, ConcreteInstr("NOP", lineno=1))

        instr = ConcreteInstr.disassemble(2, b'\td\x03\x00', 1)
        self.assertEqual(instr, ConcreteInstr("LOAD_CONST", 3, lineno=2))

        code = b'\x904\x12d\xcd\xab'
        instr = ConcreteInstr.disassemble(3, code, 0)
        self.assertEqual(instr,
                         ConcreteInstr('EXTENDED_ARG', 0x1234, lineno=3))
Beispiel #8
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)])
Beispiel #9
0
    def test_assemble(self):
        instr = ConcreteInstr("NOP")
        self.assertEqual(instr.assemble(), b'\t')

        instr = ConcreteInstr("LOAD_CONST", 3)
        self.assertEqual(instr.assemble(), b'd\x03\x00')

        instr = ConcreteInstr("LOAD_CONST", 0x1234abcd)
        self.assertEqual(instr.assemble(), b'\x904\x12d\xcd\xab')
Beispiel #10
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)
Beispiel #11
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)])
Beispiel #12
0
    def test_label(self):
        code = Bytecode()
        label = Label()
        code.extend([Instr('LOAD_CONST', 'hello', lineno=1),
                     Instr('JUMP_FORWARD', label, lineno=1),
                     label,
                     Instr('POP_TOP', lineno=1)])

        code = code.to_concrete_bytecode()
        expected = [ConcreteInstr('LOAD_CONST', 0, lineno=1),
                    ConcreteInstr('JUMP_FORWARD', 0, lineno=1),
                    ConcreteInstr('POP_TOP', lineno=1)]
        self.assertListEqual(list(code), expected)
        self.assertListEqual(code.consts, ['hello'])
Beispiel #13
0
    def test_dont_merge_constants(self):
        # test two constants which are equal but have a different type
        code = Bytecode()
        code.extend([Instr('LOAD_CONST', 5, lineno=1),
                     Instr('LOAD_CONST', 5.0, lineno=1),
                     Instr('LOAD_CONST', -0.0, lineno=1),
                     Instr('LOAD_CONST', +0.0, lineno=1)])

        code = code.to_concrete_bytecode()
        expected = [ConcreteInstr('LOAD_CONST', 0, lineno=1),
                    ConcreteInstr('LOAD_CONST', 1, lineno=1),
                    ConcreteInstr('LOAD_CONST', 2, lineno=1),
                    ConcreteInstr('LOAD_CONST', 3, lineno=1)]
        self.assertListEqual(list(code), expected)
        self.assertListEqual(code.consts, [5, 5.0, -0.0, +0.0])
Beispiel #14
0
    def test_disassemble(self):
        code = b'\t\x00d\x03' if WORDCODE else b'\td\x03\x00'
        instr = ConcreteInstr.disassemble(1, code, 0)
        self.assertEqual(instr, ConcreteInstr("NOP", lineno=1))

        instr = ConcreteInstr.disassemble(2, code, 2 if WORDCODE else 1)
        self.assertEqual(instr, ConcreteInstr("LOAD_CONST", 3, lineno=2))

        code = (b'\x90\x12\x904\x90\xabd\xcd' if WORDCODE else
                b'\x904\x12d\xcd\xab')

        instr = ConcreteInstr.disassemble(3, code, 0)
        self.assertEqual(instr,
                         ConcreteInstr('EXTENDED_ARG',
                                       0x12 if WORDCODE else 0x1234, lineno=3))
 def test_cellvars(self):
     code = Bytecode()
     code.cellvars = ["x"]
     code.freevars = ["y"]
     code.extend([
         Instr("LOAD_DEREF", CellVar("x"), lineno=1),
         Instr("LOAD_DEREF", FreeVar("y"), lineno=1),
     ])
     concrete = code.to_concrete_bytecode()
     self.assertEqual(concrete.cellvars, ["x"])
     self.assertEqual(concrete.freevars, ["y"])
     code.extend([
         ConcreteInstr("LOAD_DEREF", 0, lineno=1),
         ConcreteInstr("LOAD_DEREF", 1, lineno=1),
     ])
Beispiel #16
0
    def test_cellvar(self):
        concrete = ConcreteBytecode()
        concrete.cellvars = ['x']
        concrete.append(ConcreteInstr('LOAD_DEREF', 0))
        code = concrete.to_code()

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

        bytecode = concrete.to_bytecode()
        self.assertEqual(bytecode.cellvars, ['x'])
        self.assertEqual(list(bytecode),
                         [Instr('LOAD_DEREF', CellVar('x'), lineno=1)])
Beispiel #17
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)
Beispiel #18
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),
         ],
     )
Beispiel #19
0
    def test_async_gen_no_flag_is_async_False(self):
        # Test inference when we request a non-async function

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

        # Abort on coroutine
        code = ConcreteBytecode()
        code.append(ConcreteInstr("GET_AWAITABLE"))
        code.flags = CompilerFlags(CompilerFlags.COROUTINE)
        with self.assertRaises(ValueError):
            code.update_flags(is_async=False)
Beispiel #20
0
 def test_attr(self):
     instr = ConcreteInstr("LOAD_CONST", 5, lineno=12)
     self.assertEqual(instr.name, "LOAD_CONST")
     self.assertEqual(instr.opcode, 100)
     self.assertEqual(instr.arg, 5)
     self.assertEqual(instr.lineno, 12)
     self.assertEqual(instr.size, 2)
Beispiel #21
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')
        code = types.CodeType(code.co_argcount, 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)

        # 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)
Beispiel #22
0
    def test_set(self):
        instr = ConcreteInstr('LOAD_CONST', 5, lineno=3)

        instr.set('NOP')
        self.assertEqual(instr.name, 'NOP')
        self.assertIs(instr.arg, UNSET)
        self.assertEqual(instr.lineno, 3)

        instr.set('LOAD_FAST', 8)
        self.assertEqual(instr.name, 'LOAD_FAST')
        self.assertEqual(instr.arg, 8)
        self.assertEqual(instr.lineno, 3)

        # invalid
        with self.assertRaises(ValueError):
            instr.set('LOAD_CONST')
        with self.assertRaises(ValueError):
            instr.set('NOP', 5)
    def test_label(self):
        code = Bytecode()
        label = Label()
        code.extend([
            Instr("LOAD_CONST", "hello", lineno=1),
            Instr("JUMP_FORWARD", label, lineno=1),
            label,
            Instr("POP_TOP", lineno=1),
        ])

        code = code.to_concrete_bytecode()
        expected = [
            ConcreteInstr("LOAD_CONST", 0, lineno=1),
            ConcreteInstr("JUMP_FORWARD", 0, lineno=1),
            ConcreteInstr("POP_TOP", lineno=1),
        ]
        self.assertListEqual(list(code), expected)
        self.assertListEqual(code.consts, ["hello"])
Beispiel #24
0
    def test_set(self):
        instr = ConcreteInstr("LOAD_CONST", 5, lineno=3)

        instr.set("NOP")
        self.assertEqual(instr.name, "NOP")
        self.assertIs(instr.arg, UNSET)
        self.assertEqual(instr.lineno, 3)

        instr.set("LOAD_FAST", 8)
        self.assertEqual(instr.name, "LOAD_FAST")
        self.assertEqual(instr.arg, 8)
        self.assertEqual(instr.lineno, 3)

        # invalid
        with self.assertRaises(ValueError):
            instr.set("LOAD_CONST")
        with self.assertRaises(ValueError):
            instr.set("NOP", 5)
Beispiel #25
0
    def test_extended_arg(self):
        # Create a code object from arbitrary bytecode
        co_code = b"\x90\x12\x904\x90\xabd\xcd"
        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)
        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),
        ]
        self.assertListEqual(list(bytecode), expected)
Beispiel #26
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")
Beispiel #27
0
    def test_get_jump_target(self):
        jump_abs = ConcreteInstr("JUMP_ABSOLUTE", 3)
        self.assertEqual(jump_abs.get_jump_target(100), 3)

        jump_forward = ConcreteInstr("JUMP_FORWARD", 5)
        self.assertEqual(jump_forward.get_jump_target(10),
                         17 if WORDCODE else 18)
Beispiel #28
0
    def test_setlineno(self):
        # x = 7
        # y = 8
        # z = 9
        code = Bytecode()
        code.first_lineno = 3
        code.extend([
            Instr("LOAD_CONST", 7),
            Instr("STORE_NAME", 'x'),
            SetLineno(4),
            Instr("LOAD_CONST", 8),
            Instr("STORE_NAME", 'y'),
            SetLineno(5),
            Instr("LOAD_CONST", 9),
            Instr("STORE_NAME", 'z')
        ])

        concrete = code.to_concrete_bytecode()
        self.assertEqual(concrete.consts, [7, 8, 9])
        self.assertEqual(concrete.names, ['x', 'y', 'z'])
        code.extend([
            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)
        ])
Beispiel #29
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)
Beispiel #30
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')
Beispiel #31
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),
            ],
        )
    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()
        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"\x06\x01\x06\x01")
Beispiel #33
0
    def test_setlineno(self):
        # x = 7
        # y = 8
        # z = 9
        code = Bytecode()
        code.first_lineno = 3
        code.extend(
            [
                Instr("LOAD_CONST", 7),
                Instr("STORE_NAME", "x"),
                SetLineno(4),
                Instr("LOAD_CONST", 8),
                Instr("STORE_NAME", "y"),
                SetLineno(5),
                Instr("LOAD_CONST", 9),
                Instr("STORE_NAME", "z"),
            ]
        )

        concrete = code.to_concrete_bytecode()
        self.assertEqual(concrete.consts, [7, 8, 9])
        self.assertEqual(concrete.names, ["x", "y", "z"])
        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),
            ],
        )
Beispiel #34
0
    def test_set(self):
        instr = ConcreteInstr('LOAD_CONST', 5, lineno=3)

        instr.set('NOP')
        self.assertEqual(instr.name, 'NOP')
        self.assertIs(instr.arg, UNSET)
        self.assertEqual(instr.lineno, 3)

        instr.set('LOAD_FAST', 8)
        self.assertEqual(instr.name, 'LOAD_FAST')
        self.assertEqual(instr.arg, 8)
        self.assertEqual(instr.lineno, 3)

        # invalid
        with self.assertRaises(ValueError):
            instr.set('LOAD_CONST')
        with self.assertRaises(ValueError):
            instr.set('NOP', 5)
Beispiel #35
0
    def test_assemble(self):
        instr = ConcreteInstr("NOP")
        self.assertEqual(instr.assemble(), b'\t')

        instr = ConcreteInstr("LOAD_CONST", 3)
        self.assertEqual(instr.assemble(), b'd\x03\x00')

        instr = ConcreteInstr("LOAD_CONST", 0x1234abcd)
        self.assertEqual(instr.assemble(), b'\x904\x12d\xcd\xab')
Beispiel #36
0
    def test_assemble(self):
        instr = ConcreteInstr("NOP")
        self.assertEqual(instr.assemble(), b'\t\x00' if WORDCODE else b'\t')

        instr = ConcreteInstr("LOAD_CONST", 3)
        self.assertEqual(instr.assemble(),
                         b'd\x03' if WORDCODE else b'd\x03\x00')

        instr = ConcreteInstr("LOAD_CONST", 0x1234abcd)
        self.assertEqual(instr.assemble(),
                         (b'\x90\x12\x904\x90\xabd\xcd' if WORDCODE else
                          b'\x904\x12d\xcd\xab'))

        instr = ConcreteInstr("LOAD_CONST", 3, extended_args=1)
        self.assertEqual(instr.assemble(),
                         (b'\x90\x00d\x03' if WORDCODE else
                          b'\x90\x00\x00d\x03\x00'))
Beispiel #37
0
    def test_set_attr(self):
        instr = ConcreteInstr("LOAD_CONST", 5, lineno=12)

        # operator name
        instr.name = 'LOAD_FAST'
        self.assertEqual(instr.name, 'LOAD_FAST')
        self.assertEqual(instr.opcode, 124)
        self.assertRaises(TypeError, setattr, instr, 'name', 3)
        self.assertRaises(ValueError, setattr, instr, 'name', 'xxx')

        # operator code
        instr.opcode = 100
        self.assertEqual(instr.name, 'LOAD_CONST')
        self.assertEqual(instr.opcode, 100)
        self.assertRaises(ValueError, setattr, instr, 'opcode', -12)
        self.assertRaises(TypeError, setattr, instr, 'opcode', 'abc')

        # extended argument
        instr.arg = 0x1234abcd
        self.assertEqual(instr.arg, 0x1234abcd)
        self.assertEqual(instr.size, 8 if WORDCODE else 6)

        # small argument
        instr.arg = 0
        self.assertEqual(instr.arg, 0)
        self.assertEqual(instr.size, 2 if WORDCODE else 3)

        # invalid argument
        self.assertRaises(ValueError, setattr, instr, 'arg', -1)
        self.assertRaises(ValueError, setattr, instr, 'arg', 2147483647 + 1)

        # size attribute is read-only
        self.assertRaises(AttributeError, setattr, instr, 'size', 3)

        # lineno
        instr.lineno = 33
        self.assertEqual(instr.lineno, 33)
        self.assertRaises(TypeError, setattr, instr, 'lineno', 1.0)
        self.assertRaises(ValueError, setattr, instr, 'lineno', -1)