def test_hello(tracer, rpc_stub): tracer.start() x = "hello world" # LOAD_CONST, STORE_FAST y = x # LOAD_FAST, STORE_FAST x, y = y, x # ROT_TWO, STORE_FAST tracer.stop() assert tracer.events == [ Binding(target=Symbol("x"), value="hello world", lineno=6), Binding(target=Symbol("y"), value="hello world", sources={Symbol("x")}, lineno=7), Binding(target=Symbol("x"), value="hello world", sources={Symbol("y")}, lineno=8), Binding(target=Symbol("y"), value="hello world", sources={Symbol("x")}, lineno=8), ] from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_hello")
def test_continue_in_finally_with_exception(tracer, rpc_stub): """Tests POP_FINALLY when tos is an exception.""" tracer.start() # If the finally clause executes a return, break or continue statement, the saved # exception is discarded. for x in range(2): try: raise IndexError finally: continue # BREAK_LOOP (3.7) POP_FINALLY (3.8) tracer.stop() assert tracer.events == [ Binding(target=Symbol("x"), value=0, lineno=52), JumpBackToLoopStart(lineno=56, jump_target=16), Binding(target=Symbol("x"), value=1, lineno=52), JumpBackToLoopStart(lineno=56, jump_target=16), ] assert tracer.loops == [ Loop(start_offset=16, end_offset=36, start_lineno=52) ] assert_GetFrame(rpc_stub, "test_continue_in_finally_with_exception")
def test_unary_operations(tracer, rpc_stub): a = 1 tracer.start() b = +a # UNARY_POSITIVE b = -a # UNARY_NEGATIVE b = not a # UNARY_NOT b = ~a # UNARY_INVERT tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("a"), value=1, lineno=10), Binding(target=Symbol("b"), value=1, sources={Symbol("a")}, lineno=10), Binding(target=Symbol("b"), value=-1, sources={Symbol("a")}, lineno=11), Binding(target=Symbol("b"), value=False, sources={Symbol("a")}, lineno=12), Binding(target=Symbol("b"), value=-2, sources={Symbol("a")}, lineno=13), ] assert_GetFrame(rpc_stub, "test_unary_operations")
def test_miscellaneous(tracer, rpc_stub): a = "a" b = "b" c = "c" d = "d" e = [1, 2, 3] tracer.start() x = f"{a} {b:4} {c!r} {d!r:4}" # FORMAT_VALUE, BUILD_STRING x = a == b == c # ROT_THREE, _COMPARE_OP e[0] += e.pop() # DUP_TOP_TWO del e # DELETE_FAST global g x = g g = 1 # STORE_GLOBAL del g # DELETE_GLOBAL tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("a"), value="a", lineno=16), InitialValue(target=Symbol("b"), value="b", lineno=16), InitialValue(target=Symbol("c"), value="c", lineno=16), InitialValue(target=Symbol("d"), value="d", lineno=16), Binding( target=Symbol("x"), value="a b 'c' 'd' ", sources={Symbol("a"), Symbol("b"), Symbol("d"), Symbol("c")}, lineno=16, ), Binding( target=Symbol("x"), value=False, sources={Symbol("a"), Symbol("b")}, lineno=17, ), InitialValue(target=Symbol("e"), value=[1, 2, 3], lineno=18), Mutation(target=Symbol("e"), value=[1, 2], sources={Symbol("e")}, lineno=18), Mutation(target=Symbol("e"), value=[4, 2], sources={Symbol("e")}, lineno=18), Deletion(target=Symbol("e"), lineno=19), InitialValue(target=Symbol("g"), value=0, lineno=21), Binding(target=Symbol("x"), value=0, sources={Symbol("g")}, lineno=21), Binding(target=Symbol("g"), value=1, lineno=22), Deletion(target=Symbol("g"), lineno=23), ] assert_GetFrame(rpc_stub, "test_miscellaneous")
def test_attribute(tracer, rpc_stub): class A: pass a1 = A() a2 = A() a2.y = 1 tracer.start() a1.x = a2 # STORE_ATTR a1.x.y = 2 # LOAD_ATTR, STORE_ATTR del a1.x # DELETE_ATTR tracer.stop() assert tracer.events == [ InitialValue( lineno=14, target=Symbol("a2"), value='{"y": 1}', repr="<test_attribute.test_attribute.<locals>.A object>", ), InitialValue( lineno=14, target=Symbol("a1"), value="{}", repr="<test_attribute.test_attribute.<locals>.A object>", ), Mutation( lineno=14, target=Symbol("a1"), sources={Symbol("a2"), Symbol("a1")}, value='{"x": {"y": 1}}', repr="<test_attribute.test_attribute.<locals>.A object>", ), Mutation( lineno=15, target=Symbol("a1"), sources={Symbol("a1")}, value='{"x": {"y": 2}}', repr="<test_attribute.test_attribute.<locals>.A object>", ), Mutation( lineno=16, target=Symbol("a1"), sources={Symbol("a1")}, value="{}", repr="<test_attribute.test_attribute.<locals>.A object>", ), ] from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_attribute")
def test_api_tracer(tracer, rpc_stub): tracer.start() a = 1 tracer.stop() assert tracer.events == [ Binding(lineno=6, target=Symbol("a"), value="1", sources=set()) ] from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_api_tracer")
def test_basic_try_except(tracer, rpc_stub): tracer.start() try: # SETUP_EXCEPT (3.7), SETUP_FINALLY (3.8) raise IndexError("error") # RAISE_VARARGS a = 1 # POP_BLOCK except IndexError: pass # POP_EXCEPT, END_FINALLY tracer.stop() assert tracer.events == [] assert_GetFrame(rpc_stub, "test_basic_try_except")
def test_break_in_finally(tracer, rpc_stub): tracer.start() for x in range(2): try: pass finally: break # BREAK_LOOP (3.7) POP_FINALLY (3.8) tracer.stop() assert tracer.events == [Binding(target=Symbol("x"), value="0", lineno=62)] assert_GetFrame(rpc_stub, "test_break_in_finally")
def test_existing_variable_emit_initial_value(tracer, rpc_stub): x = "foo" tracer.start() y = x tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("x"), value="foo", lineno=8), Binding(target=Symbol("y"), value="foo", sources={Symbol("x")}, lineno=8), ] assert_GetFrame(rpc_stub, "test_existing_variable_emit_initial_value")
def test_try_except_finally(tracer, rpc_stub): tracer.start() try: # SETUP_EXCEPT + SETUP_FINALLY (3.7), SETUP_FINALLY (3.8) raise IndexError("error") # RAISE_VARARGS except IndexError: pass # POP_EXCEPT finally: # BEGIN_FINALLY (3.8) b = 1 # END_FINALLY tracer.stop() assert tracer.events == [Binding(target=Symbol("b"), value="1", lineno=50)] assert_GetFrame(rpc_stub, "test_try_except_finally")
def test_nested_try_except(tracer, rpc_stub): tracer.start() try: try: raise IndexError finally: a = 1 except IndexError: pass tracer.stop() assert tracer.events == [Binding(target=Symbol("a"), value="1", lineno=32)] assert_GetFrame(rpc_stub, "test_nested_try_except")
def test_module(rpc_stub): assert tracer.events == [ InitialValue(target=Symbol("x"), value=1, lineno=10), Deletion(target=Symbol("x"), lineno=10), InitialValue(target=Symbol("__annotations__"), value={}, lineno=11), Mutation( target=Symbol("__annotations__"), value={"y": int}, sources={Symbol("__annotations__") }, # `int` is a built-in so is excluded from sources. lineno=11, ), ] assert_GetFrame(rpc_stub, "test_outside_func")
def test_decorator_api(trace, rpc_stub): def f(foo): return foo @trace def decorated_func(): a = 1 b = f(a) return a + b assert decorated_func() == 2 from utils import assert_GetFrame assert_GetFrame(rpc_stub, "decorated_func")
def test_ref_outside(trace, rpc_stub): @trace def test_ref_outside_inner(): a = f() test_ref_outside_inner() assert trace.events == [ InitialValue(lineno=11, target=Symbol("f"), value=f), Binding(lineno=11, target=Symbol("a"), value=1, sources={Symbol("f")}), Return(lineno=11, value=None, sources=set()), ] from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_ref_outside_inner")
def test_jump(tracer, rpc_stub): a = [] b = "b" c = "c" tracer.start() if a: # POP_JUMP_IF_FALSE pass # JUMP_FORWARD else: x = 1 if not a: # POP_JUMP_IF_TRUE x = 2 x = a != b != c # JUMP_IF_FALSE_OR_POP x = a == b or c # JUMP_IF_TRUE_OR_POP # TODO: Test JUMP_ABSOLUTE. This requires loop instructions to be Implemented. tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("a"), value=[], lineno=12), Binding(target=Symbol("x"), value=1, lineno=15), Binding(target=Symbol("x"), value=2, lineno=18), InitialValue(target=Symbol("b"), value="b", lineno=20), InitialValue(target=Symbol("c"), value="c", lineno=20), # This is a known defect. We have no way to know `x` comes from `a`, because # the result of `a != b` only determines whether to jump to execute `b != c` # I think it's fine though. Binding( target=Symbol("x"), value=True, sources={Symbol("b"), Symbol("c")}, lineno=20, ), # Same defect here. Binding(target=Symbol("x"), value="c", sources={Symbol("c")}, lineno=21), ] assert_GetFrame(rpc_stub, "test_jump")
def test_break_in_finally_with_exception(tracer, rpc_stub): """Tests POP_FINALLY when tos is an exception.""" tracer.start() # If the finally clause executes a return, break or continue statement, the saved # exception is discarded. for x in range(2): try: raise IndexError finally: break # BREAK_LOOP (3.7) POP_FINALLY (3.8) tracer.stop() assert tracer.events == [Binding(target=Symbol("x"), value="0", lineno=82)] assert_GetFrame(rpc_stub, "test_break_in_finally_with_exception")
def test_closure(tracer, rpc_stub): tracer.start() a = 1 # LOAD_CLASSDEREF class Foo: print(a) # LOAD_CLOSURE tracer.stop() assert tracer.events == [ Binding(lineno=31, target=Symbol("a"), value=1), Binding(lineno=33, target=Symbol("Foo"), value=Foo, sources={Symbol("a")}), ] assert_GetFrame(rpc_stub, "test_closure")
def test_decorator_with_argument(trace, rpc_stub): @trace(disabled=True) def decorated_func_disabled(): a = 1 return a @trace(disabled=False) def decorated_func_enabled(): a = 2 return a decorated_func_disabled() assert not trace.frame_logger decorated_func_enabled() assert trace.frame_logger from utils import assert_GetFrame assert_GetFrame(rpc_stub, "decorated_func_enabled")
def test_closure(tracer, rpc_stub): tracer.start() a = 1 # LOAD_CLASSDEREF class Foo: print(a) # LOAD_CLOSURE tracer.stop() assert tracer.events == [ Binding(lineno=31, target=Symbol("a"), value="1"), Binding( lineno=33, target=Symbol("Foo"), value='{"py/type": "test_cellvar.test_closure.<locals>.Foo"}', sources={Symbol("a")}, ), ] assert_GetFrame(rpc_stub, "test_closure")
def test_deref(tracer, rpc_stub): a = 1 def test_deref_func(): tracer.start() nonlocal a print(a) # LOAD_DEREF a = 2 # STORE_DEREF del a # DELETE_DEREF tracer.stop() test_deref_func() assert tracer.events == [ InitialValue(lineno=12, target=Symbol("a"), value="1"), Binding(lineno=13, target=Symbol("a"), value="2", sources=set()), Deletion(lineno=14, target=Symbol("a")), ] assert_GetFrame(rpc_stub, "test_deref_func")
def test_continue_in_finally(tracer, rpc_stub): tracer.start() for x in range(2): try: pass finally: continue # BREAK_LOOP (3.7) POP_FINALLY (3.8) tracer.stop() assert tracer.events == [ Binding(target=Symbol("x"), value=0, lineno=22), JumpBackToLoopStart(lineno=26, jump_target=16), Binding(target=Symbol("x"), value=1, lineno=22), JumpBackToLoopStart(lineno=26, jump_target=16), ] assert tracer.loops == [ Loop(start_offset=16, end_offset=32, start_lineno=22) ] assert_GetFrame(rpc_stub, "test_continue_in_finally")
def test_list_comprehension(tracer, rpc_stub): tracer.start() n = 2 x = [i for i in range(n)] # MAKE_FUNCTION, GET_ITER, CALL_FUNCTION lst = ["foo", "bar"] x = [e for e in lst] tracer.stop() assert tracer.events == [ Binding(target=Symbol("n"), value="2", lineno=8), Binding(target=Symbol("x"), value="[0, 1]", lineno=9, sources={Symbol("n")}), Binding(target=Symbol("lst"), value='["foo", "bar"]', lineno=10), Binding( target=Symbol("x"), value='["foo", "bar"]', lineno=11, sources={Symbol("lst")}, ), ] assert_GetFrame(rpc_stub, "test_list_comprehension")
def test_while_loop(tracer, rpc_stub): tracer.start() i = 0 while i < 2: a = i i += 1 i = 0 while i < 2: break # BREAK_LOOP (3.7), JUMP_ABSOLUTE (>=3.8) i = 0 while i < 1: i += 1 continue # CONTINUE_LOOP (3.7), JUMP_ABSOLUTE (>=3.8) i = 0 while i < 2: i += 1 if i == 1: # This jumps to the end of the iteration, not out of loop. continue i = 0 while i < 2: i += 1 if i == 1: break while True: break else: a = 1 while False: pass else: a = 1 tracer.stop() assert tracer.events == [ Binding(lineno=8, target=Symbol("i"), value=0), Binding(lineno=10, target=Symbol("a"), value=0, sources={Symbol("i")}), Binding(lineno=11, target=Symbol("i"), value=1, sources={Symbol("i")}), JumpBackToLoopStart(lineno=11, jump_target=get_value({ "py38": 12, "py37": 14 })), Binding(lineno=10, target=Symbol("a"), value=1, sources={Symbol("i")}), Binding(lineno=11, target=Symbol("i"), value=2, sources={Symbol("i")}), JumpBackToLoopStart(lineno=11, jump_target=get_value({ "py38": 12, "py37": 14 })), ## Binding(lineno=13, target=Symbol("i"), value=0), Binding(lineno=17, target=Symbol("i"), value=0), Binding(lineno=19, target=Symbol("i"), value=1, sources={Symbol("i")}), JumpBackToLoopStart(lineno=20, jump_target=get_value({ "py38": 54, "py37": 64 })), ## Binding(lineno=22, target=Symbol("i"), value=0), Binding(lineno=24, target=Symbol("i"), value=1, sources={Symbol("i")}), JumpBackToLoopStart(lineno=26, jump_target=get_value({ "py38": 78, "py37": 92 })), Binding(lineno=24, target=Symbol("i"), value=2, sources={Symbol("i")}), JumpBackToLoopStart(lineno=25, jump_target=get_value({ "py38": 78, "py37": 92 })), ## Binding(lineno=28, target=Symbol("i"), value=0), Binding(lineno=30, target=Symbol("i"), value=1, sources={Symbol("i")}), Binding(lineno=42, target=Symbol("a"), value=1), ] assert tracer.loops == [ Loop( start_offset=get_value({ "py38": 12, "py37": 14 }), end_offset=get_value({ "py38": 32, "py37": 34 }), start_lineno=9, ), Loop( start_offset=get_value({ "py38": 54, "py37": 64 }), end_offset=get_value({ "py38": 70, "py37": 80 }), start_lineno=18, ), Loop( start_offset=get_value({ "py38": 78, "py37": 92 }), end_offset=get_value({ "py38": 102, "py37": 116 }), start_lineno=23, ), ] assert_GetFrame(rpc_stub, "test_while_loop")
def test_for_loop(tracer, rpc_stub): tracer.start() for i in range(2): # SETUP_LOOP (3.7), GET_ITER, FOR_ITER a = i # POP_BLOCK (3.7) for i in range(2): break # BREAK_LOOP (3.7), JUMP_ABSOLUTE (>=3.8) a = 1 for i in range(1): continue # CONTINUE_LOOP (3.7), JUMP_ABSOLUTE (>=3.8) a = 1 for i in range(2): if i == 0: # This jumps directly to FOR_ITER continue for i in range(2): if i == 1: break for i in range(1): break else: a = 1 for i in range(1): # One iteration loop. pass else: a = 1 tracer.stop() from cyberbrain import pprint pprint(tracer.events) expected_events = [ Binding(target=Symbol("i"), value="0", lineno=8), Binding(target=Symbol("a"), value="0", lineno=9, sources={Symbol("i")}), JumpBackToLoopStart(jump_target=get_value({ "py38": 16, "py37": 18 }), lineno=9), Binding(target=Symbol("i"), value="1", lineno=8), Binding(target=Symbol("a"), value="1", lineno=9, sources={Symbol("i")}), JumpBackToLoopStart(jump_target=get_value({ "py38": 16, "py37": 18 }), lineno=9), Binding(target=Symbol("i"), value="0", lineno=11), Binding(target=Symbol("i"), value="0", lineno=15), JumpBackToLoopStart(jump_target=get_value({ "py38": 56, "py37": 64 }), lineno=16), Binding(target=Symbol("i"), value="0", lineno=19), JumpBackToLoopStart(jump_target=get_value({ "py38": 76, "py37": 88 }), lineno=21), Binding(target=Symbol("i"), value="1", lineno=19), JumpBackToLoopStart(jump_target=get_value({ "py38": 76, "py37": 88 }), lineno=20), Binding(target=Symbol("i"), value="0", lineno=23), JumpBackToLoopStart(jump_target=get_value({ "py38": 100, "py37": 116 }), lineno=24), Binding(target=Symbol("i"), value="1", lineno=23), Binding(target=Symbol("i"), value="0", lineno=27), Binding(target=Symbol("i"), value="0", lineno=32), JumpBackToLoopStart(jump_target=get_value({ "py38": 148, "py37": 168 }), lineno=33), Binding(target=Symbol("a"), value="1", lineno=35), ] for index, event in enumerate(tracer.events): assert event == expected_events[ index], f"{event} {expected_events[index]}" print(tracer.loops) assert tracer.loops == [ Loop( start_offset=get_value({ "py38": 16, "py37": 18 }), end_offset=get_value({ "py38": 24, "py37": 26 }), start_lineno=8, ), Loop( start_offset=get_value({ "py38": 56, "py37": 64 }), end_offset=get_value({ "py38": 60, "py37": 68 }), start_lineno=15, ), Loop( start_offset=get_value({ "py38": 76, "py37": 88 }), end_offset=get_value({ "py38": 88, "py37": 100 }), start_lineno=19, ), Loop( start_offset=get_value({ "py38": 100, "py37": 116 }), end_offset=get_value({ "py38": 110, "py37": 126 }), start_lineno=23, ), Loop( start_offset=get_value({ "py38": 148, "py37": 168 }), end_offset=get_value({ "py38": 152, "py37": 172 }), start_lineno=32, ), ] assert_GetFrame(rpc_stub, "test_for_loop")
def test_call(tracer, rpc_stub): a = b = c = d = 1 counter = 0 tracer.start() def f(foo, bar, *args, **kwargs): nonlocal counter counter += 1 return counter x = f(a, b) # CALL_FUNCTION x = f(a, bar=b) # CALL_FUNCTION_KW x = f(a, b, *(c, d)) # BUILD_TUPLE_UNPACK_WITH_CALL, CALL_FUNCTION_EX(arg=0) x = f(a, *(b, c), **{"key": d}) # CALL_FUNCTION_EX(arg=1) x = f(foo=a, **{ "bar": b, "key": c }) # BUILD_MAP_UNPACK_WITH_CALL, CALL_FUNCTION_EX tracer.stop() assert tracer.events == [ InitialValue(lineno=10, target=Symbol("counter"), value="0"), Binding( lineno=10, target=Symbol("f"), value='{"repr": "<function test_call.<locals>.f>"}', sources={Symbol("counter")}, ), InitialValue(lineno=15, target=Symbol("a"), value="1"), InitialValue(lineno=15, target=Symbol("b"), value="1"), Binding( lineno=15, target=Symbol("x"), value="1", sources={Symbol("a"), Symbol("b"), Symbol("f")}, ), Binding( lineno=16, target=Symbol("x"), value="2", sources={Symbol("a"), Symbol("b"), Symbol("f")}, ), InitialValue(lineno=17, target=Symbol("c"), value="1"), InitialValue(lineno=17, target=Symbol("d"), value="1"), Binding( lineno=17, target=Symbol("x"), value="3", sources={ Symbol("d"), Symbol("f"), Symbol("a"), Symbol("c"), Symbol("b") }, ), Binding( lineno=18, target=Symbol("x"), value="4", sources={ Symbol("d"), Symbol("f"), Symbol("a"), Symbol("c"), Symbol("b") }, ), Binding( lineno=19, target=Symbol("x"), value="5", sources={Symbol("a"), Symbol("c"), Symbol("b"), Symbol("f")}, ), ] from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_call")
def test_inplace_operations(tracer, rpc_stub): a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = a11 = a12 = 2 b = 2 tracer.start() a1 **= b # INPLACE_POWER a2 *= b # INPLACE_MULTIPLY a3 //= b # INPLACE_FLOOR_DIVIDE a4 /= b # INPLACE_TRUE_DIVIDE a5 %= b # INPLACE_MODULO a6 += b # INPLACE_ADD a7 -= b # INPLACE_SUBTRACT a8 <<= b # INPLACE_LSHIFT a9 >>= b # INPLACE_RSHIFT a10 &= b # INPLACE_AND a11 ^= b # INPLACE_XOR a12 |= b # INPLACE_OR tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("a1"), value="2", lineno=11), InitialValue(target=Symbol("b"), value="2", lineno=11), Binding( target=Symbol("a1"), value="4", sources={Symbol("a1"), Symbol("b")}, lineno=11, ), InitialValue(target=Symbol("a2"), value="2", lineno=12), Binding( target=Symbol("a2"), value="4", sources={Symbol("a2"), Symbol("b")}, lineno=12, ), InitialValue(target=Symbol("a3"), value="2", lineno=13), Binding( target=Symbol("a3"), value="1", sources={Symbol("a3"), Symbol("b")}, lineno=13, ), InitialValue(target=Symbol("a4"), value="2", lineno=14), Binding( target=Symbol("a4"), value="1.0", sources={Symbol("a4"), Symbol("b")}, lineno=14, ), InitialValue(target=Symbol("a5"), value="2", lineno=15), Binding( target=Symbol("a5"), value="0", sources={Symbol("a5"), Symbol("b")}, lineno=15, ), InitialValue(target=Symbol("a6"), value="2", lineno=16), Binding( target=Symbol("a6"), value="4", sources={Symbol("a6"), Symbol("b")}, lineno=16, ), InitialValue(target=Symbol("a7"), value="2", lineno=17), Binding( target=Symbol("a7"), value="0", sources={Symbol("a7"), Symbol("b")}, lineno=17, ), InitialValue(target=Symbol("a8"), value="2", lineno=18), Binding( target=Symbol("a8"), value="8", sources={Symbol("a8"), Symbol("b")}, lineno=18, ), InitialValue(target=Symbol("a9"), value="2", lineno=19), Binding( target=Symbol("a9"), value="0", sources={Symbol("a9"), Symbol("b")}, lineno=19, ), InitialValue(target=Symbol("a10"), value="2", lineno=20), Binding( target=Symbol("a10"), value="2", sources={Symbol("a10"), Symbol("b")}, lineno=20, ), InitialValue(target=Symbol("a11"), value="2", lineno=21), Binding( target=Symbol("a11"), value="0", sources={Symbol("a11"), Symbol("b")}, lineno=21, ), InitialValue(target=Symbol("a12"), value="2", lineno=22), Binding( target=Symbol("a12"), value="2", sources={Symbol("a12"), Symbol("b")}, lineno=22, ), ] assert_GetFrame(rpc_stub, "test_inplace_operations")
def test_binary_operation(tracer, rpc_stub): a = b = 1 lst = [0, 1] tracer.start() c = a**b # BINARY_POWER c = a * b # BINARY_MULTIPLY c = a // b # BINARY_FLOOR_DIVIDE c = a / b # BINARY_TRUE_DIVIDE c = a % b # BINARY_MODULO c = a + b # BINARY_ADD c = a - b # BINARY_SUBTRACT c = lst[a] # BINARY_SUBSCR c = a << b # BINARY_LSHIFT c = a >> b # BINARY_RSHIFT c = a & b # BINARY_AND c = a ^ b # BINARY_XOR c = a | b # BINARY_OR tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("a"), value=1, lineno=10), InitialValue(target=Symbol("b"), value=1, lineno=10), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("b")}, lineno=10), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("b")}, lineno=11), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("b")}, lineno=12), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("b")}, lineno=13), Binding(target=Symbol("c"), value=0, sources={Symbol("a"), Symbol("b")}, lineno=14), Binding(target=Symbol("c"), value=2, sources={Symbol("a"), Symbol("b")}, lineno=15), Binding(target=Symbol("c"), value=0, sources={Symbol("a"), Symbol("b")}, lineno=16), InitialValue(target=Symbol("lst"), value=[0, 1], lineno=17), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("lst")}, lineno=17), Binding(target=Symbol("c"), value=2, sources={Symbol("a"), Symbol("b")}, lineno=18), Binding(target=Symbol("c"), value=0, sources={Symbol("a"), Symbol("b")}, lineno=19), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("b")}, lineno=20), Binding(target=Symbol("c"), value=0, sources={Symbol("a"), Symbol("b")}, lineno=21), Binding(target=Symbol("c"), value=1, sources={Symbol("a"), Symbol("b")}, lineno=22), ] from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_binary_operation")
def test_with(tracer, rpc_stub): class ContextManagerNoReturn: def __enter__(self): pass def __exit__(self, *unused): pass class ContextManagerWithReturn: def __enter__(self): return 2 def __exit__(self, *unused): pass tracer.start() with ContextManagerNoReturn(): # SETUP_WITH,WITH_CLEANUP_START,WITH_CLEANUP_FINISH a = 1 with ContextManagerWithReturn() as b: pass with ContextManagerWithReturn() as c, ContextManagerNoReturn() as d: pass with ContextManagerWithReturn() as e: with ContextManagerWithReturn() as f: pass with ContextManagerNoReturn(): try: g = 1 raise RuntimeError except RuntimeError: pass for i in range(1): with ContextManagerNoReturn(): continue tracer.stop() expected_events = [ InitialValue( lineno=21, target=Symbol("ContextManagerNoReturn"), value='{"py/type": "test_with.test_with.<locals>.ContextManagerNoReturn"}', ), Binding(lineno=22, target=Symbol("a"), value="1", sources=set()), InitialValue( lineno=24, target=Symbol("ContextManagerWithReturn"), value='{"py/type": "test_with.test_with.<locals>.ContextManagerWithReturn"}', ), Binding( lineno=24, target=Symbol("b"), value="2", sources={Symbol("ContextManagerWithReturn")}, ), Binding( lineno=27, target=Symbol("c"), value="2", sources={Symbol("ContextManagerWithReturn")}, ), Binding( lineno=27, target=Symbol("d"), value="null", sources={Symbol("ContextManagerNoReturn")}, ), Binding( lineno=30, target=Symbol("e"), value="2", sources={Symbol("ContextManagerWithReturn")}, ), Binding( lineno=31, target=Symbol("f"), value="2", sources={Symbol("ContextManagerWithReturn")}, ), Binding(lineno=36, target=Symbol("g"), value="1", sources=set()), Binding(lineno=41, target=Symbol("i"), value="0", sources=set()), ] from utils import python_version if python_version == "py38": expected_events.append(JumpBackToLoopStart(lineno=43, jump_target=208)) assert tracer.events == expected_events from utils import assert_GetFrame assert_GetFrame(rpc_stub, "test_with")
def test_unpack(tracer, rpc_stub): l1 = [1, 2] numbers = [1, 2, 3, 4] m1 = m2 = {1: 2} tracer.start() a, b = "hi" # UNPACK_SEQUENCE a, b = l1 # UNPACK_SEQUENCE first, *rest = numbers # UNPACK_EX *beginning, last = numbers # UNPACK_EX head, *middle, tail = numbers # UNPACK_EX a = *l1, *numbers a = [*l1, *numbers] a = {*l1, *numbers} a = {**m1, **m2} # TODO: Test dictionary items() unpack once iter_xx, call_xx, block_xx are done. tracer.stop() assert tracer.events == [ Binding(target=Symbol("a"), value="h", sources=set(), lineno=12), Binding(target=Symbol("b"), value="i", sources=set(), lineno=12), InitialValue(target=Symbol("l1"), value=[1, 2], lineno=13), Binding(target=Symbol("a"), value=1, sources={Symbol("l1")}, lineno=13), Binding(target=Symbol("b"), value=2, sources={Symbol("l1")}, lineno=13), InitialValue(target=Symbol("numbers"), value=[1, 2, 3, 4], lineno=14), Binding(target=Symbol("first"), value=1, sources={Symbol("numbers")}, lineno=14), Binding( target=Symbol("rest"), value=[2, 3, 4], sources={Symbol("numbers")}, lineno=14, ), Binding( target=Symbol("beginning"), value=[1, 2, 3], sources={Symbol("numbers")}, lineno=15, ), Binding(target=Symbol("last"), value=4, sources={Symbol("numbers")}, lineno=15), Binding(target=Symbol("head"), value=1, sources={Symbol("numbers")}, lineno=16), Binding( target=Symbol("middle"), value=[2, 3], sources={Symbol("numbers")}, lineno=16, ), Binding(target=Symbol("tail"), value=4, sources={Symbol("numbers")}, lineno=16), Binding( target=Symbol("a"), value=(1, 2, 1, 2, 3, 4), sources={Symbol("l1"), Symbol("numbers")}, lineno=17, ), Binding( target=Symbol("a"), value=[1, 2, 1, 2, 3, 4], sources={Symbol("l1"), Symbol("numbers")}, lineno=18, ), Binding( target=Symbol("a"), value={1, 2, 1, 2, 3, 4}, sources={Symbol("l1"), Symbol("numbers")}, lineno=19, ), InitialValue(target=Symbol("m1"), value={1: 2}, lineno=20), InitialValue(target=Symbol("m2"), value={1: 2}, lineno=20), Binding( target=Symbol("a"), value={1: 2}, sources={Symbol("m1"), Symbol("m2")}, lineno=20, ), ] assert_GetFrame(rpc_stub, "test_unpack")
def test_container(tracer, rpc_stub): a = b = 1 c = 2 e = 0 tracer.start() d = [a, b] # BUILD_LIST d = (a, b) # BUILD_TUPLE d = {a, b} # BUILD_SET d = {a: b} # BUILD_MAP d = {1: a, 2: b} # BUILD_CONST_KEY_MAP d[a] = c # STORE_SUBSCR del d[a] # DELETE_SUBSCR d = [a, b, c][e:c] # BUILD_SLICE, [1, 1, 2][0:2] d = [b, b, c][e:c:a] # BUILD_SLICE, [1, 1, 2][0:2:1] tracer.stop() assert tracer.events == [ InitialValue(target=Symbol("a"), value=1, lineno=12), InitialValue(target=Symbol("b"), value=1, lineno=12), Binding( target=Symbol("d"), value=[1, 1], sources={Symbol("a"), Symbol("b")}, lineno=12, ), Binding( target=Symbol("d"), value=(1, 1), sources={Symbol("a"), Symbol("b")}, lineno=13, ), Binding( target=Symbol("d"), value={1}, sources={Symbol("a"), Symbol("b")}, lineno=14 ), Binding( target=Symbol("d"), value={1: 1}, sources={Symbol("a"), Symbol("b")}, lineno=15, ), Binding( target=Symbol("d"), value={1: 1, 2: 1}, sources={Symbol("a"), Symbol("b")}, lineno=16, ), InitialValue(target=Symbol("c"), value=2, lineno=17), Mutation( target=Symbol("d"), value={1: 2, 2: 1}, sources={Symbol("d"), Symbol("a"), Symbol("c")}, lineno=17, ), Mutation( target=Symbol("d"), value={2: 1}, sources={Symbol("d"), Symbol("a")}, lineno=18, ), InitialValue(target=Symbol("e"), value=0, lineno=19), Binding( target=Symbol("d"), value=[1, 1], sources={Symbol("a"), Symbol("b"), Symbol("c"), Symbol("e")}, lineno=19, ), Binding( target=Symbol("d"), value=[1, 1], sources={Symbol("a"), Symbol("b"), Symbol("c"), Symbol("e")}, lineno=20, ), ] assert_GetFrame(rpc_stub, "test_container")