Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# equal
code1 = BytecodeBlocks()
label1 = Label()
code1[0][:] = [Instr(1, "JUMP_FORWARD", label1),
Instr(1, "NOP"),
label1]
code2 = BytecodeBlocks()
label2 = Label()
code2[0][:] = [Instr(1, "JUMP_FORWARD", label2),
Label(), # unused label
Instr(1, "NOP"),
label2]
self.assertEqual(code2, code1)
# not equal
code3 = BytecodeBlocks()
label3 = Label()
code3[0][:] = [Instr(1, "JUMP_FORWARD", label3),
label3,
Instr(1, "NOP")]
self.assertNotEqual(code3, code1)
def test_concrete_code_dont_merge_constants(self):
# test two constants which are equal but have a different type
code = BytecodeBlocks()
block = code[0]
block.append(Instr(1, 'LOAD_CONST', 5))
block.append(Instr(1, 'LOAD_CONST', 5.0))
code = code.to_concrete_bytecode()
expected = [ConcreteInstr(1, 'LOAD_CONST', 0),
ConcreteInstr(1, 'LOAD_CONST', 1)]
self.assertListEqual(list(code), expected)
self.assertListEqual(code.consts, [5, 5.0])
def test_constructor(self):
code = BytecodeBlocks()
self.assertEqual(code.name, "")
self.assertEqual(code.filename, "")
self.assertEqual(code.flags, 0)
self.assertBlocksEqual(code, [])
def test_add_del_block(self):
code = BytecodeBlocks()
code[0].append(LOAD_CONST(0))
block = code.add_block()
self.assertEqual(len(code), 2)
self.assertIs(block, code[1])
code[1].append(LOAD_CONST(2))
self.assertBlocksEqual(code,
[LOAD_CONST(0)],
[LOAD_CONST(2)])
del code[0]
self.assertBlocksEqual(code,
[LOAD_CONST(2)])
def disassemble(source, *, filename="", function=False,
remove_last_return_none=False):
code = get_code(source, filename=filename, function=function)
bytecode = BytecodeBlocks.from_code(code)
if remove_last_return_none:
# drop LOAD_CONST+RETURN_VALUE to only keep 2 instructions,
# to make unit tests shorter
block = bytecode[-1]
test = (block[-2].name == "LOAD_CONST"
and block[-2].arg is None
and block[-1].name == "RETURN_VALUE")
if not test:
raise ValueError("unable to find implicit RETURN_VALUE : %s"
% block[-2:])
del block[-2:]
return bytecode
def test_to_bytecode(self):
blocks = BytecodeBlocks()
label = blocks.add_block().label
blocks[0].extend([Instr(1, 'LOAD_NAME', 'test'),
Instr(1, 'POP_JUMP_IF_FALSE', label),
Instr(2, 'LOAD_CONST', 5),
Instr(2, 'STORE_NAME', 'x'),
Instr(2, 'JUMP_FORWARD', label),
Instr(4, 'LOAD_CONST', 7),
Instr(4, 'STORE_NAME', 'x')])
blocks[1].extend([Instr(4, 'LOAD_CONST', None),
Instr(4, 'RETURN_VALUE')])
bytecode = blocks.to_bytecode()
label = Label()
self.assertEqual(bytecode,
[Instr(1, 'LOAD_NAME', 'test'),
Instr(1, 'POP_JUMP_IF_FALSE', label),
def assertBytecodeEqual(self, code, *expected_blocks):
expected = bytecode.BytecodeBlocks()
expected.argnames = code.argnames
del expected[0]
for block in expected_blocks:
expected.add_block(block)
bytecode._dump_code(code)
print("*")
bytecode._dump_code(expected)
print(type(code))
print(type(expected))
self.assertEqual(code, expected)
def test_return_value(self):
# return+return: remove second return
#
# def func():
# return 4
# return 5
code = Bytecode([Instr('LOAD_CONST', 4, lineno=2),
Instr('RETURN_VALUE', lineno=2),
Instr('LOAD_CONST', 5, lineno=3),
Instr('RETURN_VALUE', lineno=3)])
code = BytecodeBlocks._from_bytecode(code, split_final=False)
self.check(code,
Instr('LOAD_CONST', 4, lineno=2),
Instr('RETURN_VALUE', lineno=2))
# return+return + return+return: remove second and fourth return
#
# def func():
# return 4
# return 5
# return 6
# return 7
code = Bytecode([Instr('LOAD_CONST', 4, lineno=2),
Instr('RETURN_VALUE', lineno=2),
Instr('LOAD_CONST', 5, lineno=3),
Instr('RETURN_VALUE', lineno=3),
Instr('LOAD_CONST', 6, lineno=4),
def test_concrete_code_labels(self):
code = BytecodeBlocks()
label = Label()
code[0].append(Instr(1, 'LOAD_CONST', 'hello'))
code[0].append(Instr(1, 'JUMP_FORWARD', label))
code[0].append(label)
code[0].append(Instr(1, 'POP_TOP'))
code = code.to_concrete_bytecode()
expected = [ConcreteInstr(1, 'LOAD_CONST', 0),
ConcreteInstr(1, 'JUMP_FORWARD', 0),
ConcreteInstr(1, 'POP_TOP')]
self.assertListEqual(list(code), expected)
self.assertListEqual(code.consts, ['hello'])
def test_eq_labels(self):
# equal
code1 = BytecodeBlocks()
label1 = Label()
code1[0][:] = [Instr(1, "JUMP_FORWARD", label1),
Instr(1, "NOP"),
label1]
code2 = BytecodeBlocks()
label2 = Label()
code2[0][:] = [Instr(1, "JUMP_FORWARD", label2),
Label(), # unused label
Instr(1, "NOP"),
label2]
self.assertEqual(code2, code1)
# not equal
code3 = BytecodeBlocks()
label3 = Label()
code3[0][:] = [Instr(1, "JUMP_FORWARD", label3),