def test_lnotab_roundtrip(): # DO NOT ADD EXTRA LINES HERE def f(): # pragma: no cover a = 1 b = 2 c = 3 d = 4 a, b, c, d start_line = test_lnotab_roundtrip.__code__.co_firstlineno + 3 lines = [start_line + n for n in range(5)] code = Code.from_pycode(f.__code__) lnotab = code.lnotab assert lnotab.keys() == set(lines) assert isinstance(lnotab[lines[0]], LOAD_CONST) assert lnotab[lines[0]].arg == 1 assert isinstance(lnotab[lines[1]], LOAD_CONST) assert lnotab[lines[1]].arg == 2 assert isinstance(lnotab[lines[2]], LOAD_CONST) assert lnotab[lines[2]].arg == 3 assert isinstance(lnotab[lines[3]], LOAD_CONST) assert lnotab[lines[3]].arg == 4 assert isinstance(lnotab[lines[4]], LOAD_FAST) assert lnotab[lines[4]].arg == 'a' assert f.__code__.co_lnotab == code.py_lnotab == code.to_pycode().co_lnotab
def test_code_flags(sample_flags): attr_map = { 'CO_NESTED': 'is_nested', 'CO_GENERATOR': 'is_generator', 'CO_COROUTINE': 'is_coroutine', 'CO_ITERABLE_COROUTINE': 'is_iterable_coroutine', 'CO_NEWLOCALS': 'constructs_new_locals', } for flags in sample_flags: code = Code.from_pycode(pycode( argcount=0, kwonlyargcount=0, nlocals=2, stacksize=0, flags=Flag.pack(**flags), codestring=b'd\x00\x00S', # return None constants=(None,), names=(), varnames=('a', 'b'), filename='', name='', firstlineno=0, lnotab=b'', )) assert code.flags == flags for flag, attr in attr_map.items(): if flags[flag]: assert getattr(code, attr)
def abc_code(): a = LOAD_CONST('a') b = LOAD_CONST('b') c = LOAD_CONST('c') # not in instrs code = Code((a, b), argnames=()) return (a, b, c), code
def test_precomputed_slices_non_const(): transformer = precomputed_slices() def f(a, b): with_non_const = a[b] with_mixed = a[1, b] return with_non_const, with_mixed transformed = transformer(f) f_instrs = Code.from_pyfunc(f).instrs transformed_instrs = Code.from_pyfunc(transformed).instrs for orig, xformed in zip(f_instrs, transformed_instrs): assert orig.equiv(xformed)
def test_dangling_var(cls): instr = cls('dangling') with pytest.raises(ValueError) as e: Code((instr,)) assert ( str(e.value) == "Argument to %r is not in cellvars or freevars." % instr )
def test_code_multiple_kwargs(): with pytest.raises(ValueError) as e: Code( (), ( '**kwargs', '**kwargs', ), ) assert str(e.value) == 'cannot specify **kwargs more than once'
def test_lnotab_really_dumb_whitespace(): ns = {} exec('def f():\n lol = True' + '\n' * 1024 + ' wut = True', ns) f = ns['f'] code = Code.from_pycode(f.__code__) lines = [2, 1026] lnotab = code.lnotab assert lnotab.keys() == set(lines) assert isinstance(lnotab[lines[0]], LOAD_CONST) assert lnotab[lines[0]].arg assert isinstance(lnotab[lines[1]], LOAD_CONST) assert lnotab[lines[1]].arg assert f.__code__.co_lnotab == code.py_lnotab == code.to_pycode().co_lnotab
def test_name(): for const in compile('class C:\n b = a', '<string>', 'exec').co_consts: if isinstance(const, CodeType): pre_transform = Code.from_pycode(const) code = asconstants(a=1).transform(pre_transform) break else: raise AssertionError('There should be a code object in there!') ns = {} exec(code.to_pycode(), ns) assert ns['b'] == 1
def test_precomputed_slices(): @precomputed_slices() def foo(a): return a[1:5] l = list(range(10)) assert foo(l) == l[1:5] assert slice(1, 5) in foo.__code__.co_consts instrs = Code.from_pyfunc(foo).instrs assert LOAD_CONST(slice(1, 5)).equiv(instrs[1]) assert BUILD_SLICE not in set(map(type, instrs))
def test_name(): for const in compile( 'class C:\n b = a', '<string>', 'exec').co_consts: if isinstance(const, CodeType): pre_transform = Code.from_pycode(const) code = asconstants(a=1).transform(pre_transform) break else: raise AssertionError('There should be a code object in there!') ns = {} exec(code.to_pycode(), ns) assert ns['b'] == 1