def test_yield_from(trace, mocked_responses): def inner(): for i in range(2): yield i @trace def yield_from_function(): yield from inner() # CALL_FUNCTION, GET_YIELD_FROM_ITER, LOAD_CONST # The above line triggers two return events for sys.settrace for output in yield_from_function(): print(output) trace.stop() assert trace.events == [ InitialValue( lineno=75, target=Symbol("inner"), value='{"repr": "<function test_yield_from.<locals>.inner>"}', repr="<function test_yield_from.<locals>.inner>", ), Return( lineno=75, value="null", repr="None", sources=set(), ), ]
def test_recursion_decorator(trace): @trace def fib(n): if n <= 1: return n else: return fib(n - 1) + fib(n - 2) print(fib(3)) assert trace.events == [ InitialValue( lineno=7, target=Symbol("n"), value="3", repr="3", ), InitialValue( lineno=10, target=Symbol("fib"), value= '{"repr": "<function test_recursion_decorator.<locals>.fib>"}', repr="<function test_recursion_decorator.<locals>.fib>", ), Return( lineno=10, value="2", repr="2", sources={Symbol("fib"), Symbol("n")}, ), ]
def test_trace_decorated_function(trace): def my_decorator(f): def inner(*args): a = 1 f(*args) b = a return inner @my_decorator @trace def original_func(): a = [1, 2, 3] original_func() assert trace.events == [ Binding( lineno=16, target=Symbol("a"), value="[1,2,3]", repr="[1, 2, 3]", sources=set(), ), Return( lineno=16, value="null", repr="None", sources=set(), ), ]
def test_decorator_multiple_times(trace, rpc_stub): @trace def func(b): a = b return a func(1) # Test that server wait does not block user code execution. trace._wait_for_termination() assert func(2) == 2 from cyberbrain import pprint pprint(trace.events) assert trace.events == [ InitialValue( lineno=21, target=Symbol("b"), value="1", ), Binding(lineno=21, target=Symbol("a"), value="1", sources={Symbol("b")}), Return(lineno=22, value="1", sources={Symbol("a")}), ] trace.server.stop()
def test_ref_outside(trace, mocked_responses): @trace def test_ref_outside_inner(): a = f() test_ref_outside_inner() assert trace.events == [ InitialValue(lineno=-1, target=Symbol("f"), value='{"repr": "<function f>"}'), Binding(lineno=11, target=Symbol("a"), value="1", sources={Symbol("f")}), Return(lineno=11, value="null", sources=set()), ]
def test_ref_outside(trace, test_server): @trace def test_ref_outside_inner(): a = f() test_ref_outside_inner() assert trace.events == [ InitialValue(lineno=11, target=Symbol("f"), value='{"repr": "<function f>"}'), Binding(lineno=11, target=Symbol("a"), value="1", sources={Symbol("f")}), Return(lineno=11, value="null", sources=set()), ] test_server.assert_frame_sent("test_ref_outside_inner")
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_while_jump_to_zero(trace): @trace def while_jump_to_zero(count): while count > 0: count -= 1 while_jump_to_zero(2) assert trace.events == [ InitialValue( lineno=103, target=Symbol("count"), value="2", repr="2", ), Binding( lineno=104, target=Symbol("count"), value="1", repr="1", sources={Symbol("count")}, ), JumpBackToLoopStart(lineno=104, jump_target=get_value({ "py37": 2, "default": 0 })), Binding( lineno=104, target=Symbol("count"), value="0", repr="0", sources={Symbol("count")}, ), JumpBackToLoopStart(lineno=104, jump_target=get_value({ "py37": 2, "default": 0 })), Return( lineno=104, value="null", repr="None", sources=set(), ), ]
def test_decorator_multiple_times(trace, mocked_responses): @trace def func(b): a = b return a func(1) assert func(2) == 2 assert trace.events == [ InitialValue( lineno=21, target=Symbol("b"), value="1", ), Binding(lineno=21, target=Symbol("a"), value="1", sources={Symbol("b")}), Return(lineno=22, value="1", sources={Symbol("a")}), ]
def test_generator_function(trace, mocked_responses): @trace def generator_function(count): while count > 0: x = yield count # YIELD_VALUE, POP_TOP, triggers a return event. count -= 1 gen = generator_function(2) for _ in gen: gen.send("foo") # Remember that .send will yield the next value. trace.stop() assert trace.events == [ InitialValue( lineno=8, target=Symbol("count"), value="2", repr="2", ), Binding( lineno=9, target=Symbol("x"), value='"foo"', repr='"foo"', sources=set(), ), Binding( lineno=10, target=Symbol("count"), value="1", repr="1", sources={Symbol("count")}, ), JumpBackToLoopStart(lineno=10, jump_target=get_value({ "py37": 2, "default": 0 })), Binding( lineno=9, target=Symbol("x"), value="null", repr="None", sources=set(), ), Binding( lineno=10, target=Symbol("count"), value="0", repr="0", sources={Symbol("count")}, ), JumpBackToLoopStart(lineno=10, jump_target=get_value({ "py37": 2, "default": 0 })), Return( lineno=10, value="null", repr="None", sources=set(), ), ]