1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
import unittest
from bytecode import Bytecode, ConcreteBytecode, ControlFlowGraph
from . import TestCase, get_code
class CodeTests(TestCase):
"""Check that bytecode.from_code(code).to_code() returns code."""
def check(self, source, function=False):
ref_code = get_code(source, function=function)
code = ConcreteBytecode.from_code(ref_code).to_code()
self.assertCodeObjectEqual(ref_code, code)
code = Bytecode.from_code(ref_code).to_code()
self.assertCodeObjectEqual(ref_code, code)
bytecode = Bytecode.from_code(ref_code)
blocks = ControlFlowGraph.from_bytecode(bytecode)
code = blocks.to_bytecode().to_code()
self.assertCodeObjectEqual(ref_code, code)
def test_loop(self):
self.check(
"""
for x in range(1, 10):
x += 1
if x == 3:
continue
x -= 1
if x > 7:
break
x = 0
print(x)
"""
)
def test_varargs(self):
self.check(
"""
def func(a, b, *varargs):
pass
""",
function=True,
)
def test_kwargs(self):
self.check(
"""
def func(a, b, **kwargs):
pass
""",
function=True,
)
def test_kwonlyargs(self):
self.check(
"""
def func(*, arg, arg2):
pass
""",
function=True,
)
# Added because Python 3.10 added some special behavior with respect to
# generators in term of stack size
def test_generator_func(self):
self.check(
"""
def func(arg, arg2):
yield
""",
function=True,
)
def test_async_func(self):
self.check(
"""
async def func(arg, arg2):
pass
""",
function=True,
)
if __name__ == "__main__":
unittest.main() # pragma: no cover
|