Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_to_code(self):
instr = ConcreteInstr(1, "NOP")
self.assertEqual(instr.assemble(), b'\t')
instr = ConcreteInstr(1, "LOAD_CONST", 3)
self.assertEqual(instr.assemble(), b'd\x03\x00')
instr = ConcreteInstr(1, "LOAD_CONST", 0x1234abcd)
self.assertEqual(instr.assemble(), b'\x904\x12d\xcd\xab')
Instr(4, 'LOAD_CONST', 7),
Instr(4, 'STORE_NAME', 'x'),
label,
Instr(4, 'LOAD_CONST', None),
Instr(4, 'RETURN_VALUE')])
concrete = bytecode.to_concrete_bytecode()
expected = [ConcreteInstr(1, 'LOAD_NAME', 0),
ConcreteInstr(1, 'POP_JUMP_IF_FALSE', 21),
ConcreteInstr(2, 'LOAD_CONST', 0),
ConcreteInstr(2, 'STORE_NAME', 1),
ConcreteInstr(2, 'JUMP_FORWARD', 6),
ConcreteInstr(4, 'LOAD_CONST', 1),
ConcreteInstr(4, 'STORE_NAME', 1),
ConcreteInstr(4, 'LOAD_CONST', 2),
ConcreteInstr(4, 'RETURN_VALUE')]
self.assertListEqual(list(concrete), expected)
self.assertListEqual(concrete.consts, [5, 7, None])
self.assertListEqual(concrete.names, ['test', 'x'])
self.assertListEqual(concrete.varnames, [])
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(1, "LOAD_CONST", 0x1234abcd)])
# with EXTENDED_ARG opcode
bytecode = ConcreteBytecode.from_code(code, extended_arg_op=True)
self.assertListEqual(list(bytecode),
[ConcreteInstr(1, 'EXTENDED_ARG', 0x1234),
ConcreteInstr(1, 'LOAD_CONST', 0xabcd)])
def test_mimicks_c_impl_extended_arg(self):
with mock.patch.object(peephole_opt, 'MIMICK_C_IMPL', True):
# create code with EXTENDED_ARG opcode
block = [
ConcreteInstr('LOAD_CONST', 3 << 16, lineno=1),
ConcreteInstr('POP_TOP', lineno=1),
ConcreteInstr('LOAD_CONST', 0, lineno=1),
ConcreteInstr('LOAD_CONST', 1, lineno=1),
ConcreteInstr('BINARY_ADD', lineno=1),
ConcreteInstr('STORE_NAME', 0, lineno=1),
ConcreteInstr('LOAD_CONST', 2, lineno=1),
ConcreteInstr('RETURN_VALUE', lineno=1),
]
code_noopt = ConcreteBytecode()
code_noopt.consts = [1, 2, None]
code_noopt.names = ['x']
code_noopt[:] = block
noopt = code_noopt.to_code()
# don't optimize if the code contains EXTENDED_ARG opcode
optimizer = peephole_opt._CodePeepholeOptimizer()
optim = optimizer.optimize(noopt)
self.assertIs(optim, noopt)
def test_mimicks_c_impl_extended_arg(self):
with mock.patch.object(peephole_opt, 'MIMICK_C_IMPL', True):
# create code with EXTENDED_ARG opcode
block = [
ConcreteInstr('LOAD_CONST', 3 << 16, lineno=1),
ConcreteInstr('POP_TOP', lineno=1),
ConcreteInstr('LOAD_CONST', 0, lineno=1),
ConcreteInstr('LOAD_CONST', 1, lineno=1),
ConcreteInstr('BINARY_ADD', lineno=1),
ConcreteInstr('STORE_NAME', 0, lineno=1),
ConcreteInstr('LOAD_CONST', 2, lineno=1),
ConcreteInstr('RETURN_VALUE', lineno=1),
]
code_noopt = ConcreteBytecode()
code_noopt.consts = [1, 2, None]
code_noopt.names = ['x']
code_noopt[:] = block
noopt = code_noopt.to_code()
# don't optimize if the code contains EXTENDED_ARG opcode
optimizer = peephole_opt._CodePeepholeOptimizer()
optim = optimizer.optimize(noopt)
self.assertIs(optim, noopt)
def test_disassemble_concrete(self):
code = get_code("x = 5")
bytecode = ConcreteBytecode.from_code(code)
expected = [ConcreteInstr(1, 'LOAD_CONST', 0),
ConcreteInstr(1, 'STORE_NAME', 0),
ConcreteInstr(1, 'LOAD_CONST', 1),
ConcreteInstr(1, 'RETURN_VALUE')]
self.assertListEqual(list(bytecode), expected)
self.assertEqual(bytecode.consts, [5, None])
self.assertEqual(bytecode.names, ['x'])
def test_attr(self):
instr = ConcreteInstr(1, "LOAD_CONST", 5)
self.assertRaises(AttributeError, setattr, instr, 'name', 'LOAD_FAST')
self.assertRaises(AttributeError, setattr, instr, 'lineno', 1)
self.assertRaises(AttributeError, setattr, instr, 'arg', 2)
def test_concrete_code(self):
code = disassemble("""
if test:
x = 12
else:
x = 37
""")
code = code.to_concrete_bytecode()
expected = [ConcreteInstr(1, 'LOAD_NAME', 0),
ConcreteInstr(1, 'POP_JUMP_IF_FALSE', 15),
ConcreteInstr(2, 'LOAD_CONST', 0),
ConcreteInstr(2, 'STORE_NAME', 1),
ConcreteInstr(2, 'JUMP_FORWARD', 6),
ConcreteInstr(4, 'LOAD_CONST', 1),
ConcreteInstr(4, 'STORE_NAME', 1),
ConcreteInstr(4, 'LOAD_CONST', 2),
ConcreteInstr(4, 'RETURN_VALUE')]
self.assertListEqual(list(code), expected)
self.assertListEqual(code.consts, [12, 37, None])
self.assertListEqual(code.names, ['test', 'x'])
self.assertListEqual(code.varnames, [])
def test_get_jump_target(self):
jump_abs = ConcreteInstr(1, "JUMP_ABSOLUTE", 3)
self.assertEqual(jump_abs.get_jump_target(100), 3)
jump_forward = ConcreteInstr(1, "JUMP_FORWARD", 5)
self.assertEqual(jump_forward.get_jump_target(10), 18)
def _check_instr(self, instr):
if not isinstance(instr, (Label, SetLineno, Instr, _bytecode.ConcreteInstr)):
raise ValueError(
"Bytecode must only contain Label, "
"SetLineno, Instr and ConcreteInstr objects, "
"but %s was found" % type(instr).__name__
)