def test_switch2_pingpong(self): from _continuation import continulet # def f1(c1): res = c1.switch('started 1') assert res == 'go' for i in range(10): res = c1.switch(i, to=c2) assert res == 100 + i return 42 def f2(c2): res = c2.switch('started 2') for i in range(10): assert res == i res = c2.switch(100 + i, to=c1) not_reachable # c1 = continulet(f1) c2 = continulet(f2) res = c1.switch() assert res == 'started 1' res = c2.switch() assert res == 'started 2' res = c1.switch('go') assert res == 42
def test_switch_alternate(self): from _continuation import continulet # def func_lower(c): res = c.switch('a') assert res == 'b' res = c.switch('c') assert res == 'd' return 'e' # def func_upper(c): res = c.switch('A') assert res == 'B' res = c.switch('C') assert res == 'D' return 'E' # c_lower = continulet(func_lower) c_upper = continulet(func_upper) res = c_lower.switch() assert res == 'a' res = c_upper.switch() assert res == 'A' res = c_lower.switch('b') assert res == 'c' res = c_upper.switch('B') assert res == 'C' res = c_lower.switch('d') assert res == 'e' res = c_upper.switch('D') assert res == 'E'
def test_switch2_simple(self): from _continuation import continulet # def f1(c1): res = c1.switch('started 1') assert res == 'a' res = c1.switch('b', to=c2) assert res == 'c' return 42 def f2(c2): res = c2.switch('started 2') assert res == 'b' res = c2.switch('c', to=c1) not_reachable # c1 = continulet(f1) c2 = continulet(f2) res = c1.switch() assert res == 'started 1' res = c2.switch() assert res == 'started 2' res = c1.switch('a') assert res == 42
def depth1(c): seen.append(1) try: continulet(depth2).switch() except ValueError: seen.append(3) return 4
def test_switch_alternate(self): from _continuation import continulet # def func_lower(c): res = c.switch("a") assert res == "b" res = c.switch("c") assert res == "d" return "e" # def func_upper(c): res = c.switch("A") assert res == "B" res = c.switch("C") assert res == "D" return "E" # c_lower = continulet(func_lower) c_upper = continulet(func_upper) res = c_lower.switch() assert res == "a" res = c_upper.switch() assert res == "A" res = c_lower.switch("b") assert res == "c" res = c_upper.switch("B") assert res == "C" res = c_lower.switch("d") assert res == "e" res = c_upper.switch("D") assert res == "E"
def test_switch2_immediately_away(self): from _continuation import continulet # def f1(c1): print("in f1") return "m" # def f2(c2): res = c2.switch("z") print("got there!") assert res == "a" return None # c1 = continulet(f1) c2 = continulet(f2) res = c2.switch() assert res == "z" assert c1.is_pending() assert c2.is_pending() print("calling!") res = c1.switch("a", to=c2) print("back") assert res == "m"
def test_permute(self): import sys from _continuation import continulet, permute # def f1(c1): res = c1.switch() assert res == "ok" return "done" # def f2(c2): assert sys._getframe(1).f_code.co_name == 'main' permute(c1, c2) assert sys._getframe(1).f_code.co_name == 'f1' return "ok" # c1 = continulet(f1) c2 = continulet(f2) def main(): c1.switch() res = c2.switch() assert res == "done" main()
def test_permute(self): import sys from _continuation import continulet, permute # def f1(c1): res = c1.switch() assert res == "ok" return "done" # def f2(c2): assert sys._getframe(1).f_code.co_name == "main" permute(c1, c2) assert sys._getframe(1).f_code.co_name == "f1" return "ok" # c1 = continulet(f1) c2 = continulet(f2) def main(): c1.switch() res = c2.switch() assert res == "done" main()
def test_switch2_simple(self): from _continuation import continulet # def f1(c1): res = c1.switch("started 1") assert res == "a" res = c1.switch("b", to=c2) assert res == "c" return 42 def f2(c2): res = c2.switch("started 2") assert res == "b" res = c2.switch("c", to=c1) not_reachable # c1 = continulet(f1) c2 = continulet(f2) res = c1.switch() assert res == "started 1" res = c2.switch() assert res == "started 2" res = c1.switch("a") assert res == 42
def test_switch2_immediately_away(self): from _continuation import continulet # def f1(c1): print 'in f1' return 'm' # def f2(c2): res = c2.switch('z') print 'got there!' assert res == 'a' return None # c1 = continulet(f1) c2 = continulet(f2) res = c2.switch() assert res == 'z' assert c1.is_pending() assert c2.is_pending() print 'calling!' res = c1.switch('a', to=c2) print 'back' assert res == 'm'
def f(): c1 = continulet(s1, 123) c2 = continulet(s2, c1) c1.switch() res = c2.switch() assert res == 'b' res = c1.switch(1000) assert res == 1001 return c2.switch(2000)
def test_bug_finish_with_already_finished_stacklet(self): from _continuation import continulet, error # make an already-finished continulet c1 = continulet(lambda x: x) c1.switch() # make another continulet c2 = continulet(lambda x: x) # this switch is forbidden, because it causes a crash when c2 finishes raises(error, c1.switch, to=c2)
def test_initial_switch_must_give_None(self): from _continuation import continulet # def empty_callback(c): return 'ok' # c = continulet(empty_callback) res = c.switch(None) assert res == 'ok' # c = continulet(empty_callback) raises(TypeError, c.switch, 'foo') # "can't send non-None value"
def test_switch2_already_finished(self): from _continuation import continulet, error # def f1(c1): not_reachable def empty_callback(c): return 42 # c1 = continulet(f1) c2 = continulet(empty_callback) c2.switch() e = raises(error, c1.switch, to=c2) assert str(e.value) == "continulet already finished"
def f(): seen.append(1) c1 = continulet(s1, 123) c2 = continulet(s2, c1) c1.switch() seen.append(4) res = c2.switch() seen.append(9) assert res == 'b' res = c1.switch(1000) seen.append(11) assert res == 1001 res = c2.switch(2000) seen.append(13) return res
def test_traceback_is_complete(self): import sys from _continuation import continulet # def g(): raise KeyError def f(c): g() # def do(c): c.switch() # c = continulet(f) try: do(c) except KeyError: tb = sys.exc_info()[2] else: raise AssertionError("should have raised!") # assert tb.tb_next.tb_frame.f_code.co_name == "do" assert tb.tb_next.tb_next.tb_frame.f_code.co_name == "f" assert tb.tb_next.tb_next.tb_next.tb_frame.f_code.co_name == "g" assert tb.tb_next.tb_next.tb_next.tb_next is None
def test_switch2_not_initialized(self): from _continuation import continulet c0 = continulet.__new__(continulet) c0bis = continulet.__new__(continulet) res = c0.switch(123, to=c0) assert res == 123 res = c0.switch(123, to=c0bis) assert res == 123 raises(ValueError, c0.throw, ValueError, to=c0) raises(ValueError, c0.throw, ValueError, to=c0bis) # def f1(c1): c1.switch("a") raises(ValueError, c1.switch, "b") raises(KeyError, c1.switch, "c") return "d" c1 = continulet(f1) res = c0.switch(to=c1) assert res == "a" res = c1.switch(to=c0) assert res == "b" res = c1.throw(ValueError, to=c0) assert res == "c" res = c0.throw(KeyError, to=c1) assert res == "d"
def start_continulets(self, i=0): c = _continuation.continulet(self.run_continulet, i) self.contlist.append(c) if i < CONTINULETS: self.start_continulets(i + 1) # ^^^ start each continulet with a different base stack self.conts[c] = c # initially (i.e. not started) there are all loops
def test_f_back(self): import sys from _continuation import continulet # def g(c): c.switch(sys._getframe(0)) c.switch(sys._getframe(0).f_back) c.switch(sys._getframe(1)) c.switch(sys._getframe(1).f_back) assert sys._getframe(2) is f3.f_back c.switch(sys._getframe(2)) def f(c): g(c) # c = continulet(f) f1 = c.switch() assert f1.f_code.co_name == 'g' f2 = c.switch() assert f2.f_code.co_name == 'f' f3 = c.switch() assert f3 is f2 assert f1.f_back is f3 def main(): f4 = c.switch() assert f4.f_code.co_name == 'main', repr(f4.f_code.co_name) assert f3.f_back is f1 # not running, so a loop def main2(): f5 = c.switch() assert f5.f_code.co_name == 'main2', repr(f5.f_code.co_name) assert f3.f_back is f1 # not running, so a loop main() main2() res = c.switch() assert res is None assert f3.f_back is None
def depth1(c): seen.append(1) c2 = continulet(depth2) seen.append(2) res = c2.switch() seen.append(res) return 5
def test_exc_info_save_restore(self): from _continuation import continulet import sys main = [] def f(c): print("in f... 222") try: raise ValueError('fun') except: print("333") exc_info = sys.exc_info() print("444") c17650 = continulet(h) bd50.switch(to=c17650) print("back in f...") assert exc_info == sys.exc_info() def h(c): print("in h... 555") assert sys.exc_info() == (None, None, None) print("666") main = continulet.__new__(continulet) print(111) bd50 = continulet(f) main.switch(to=bd50) print(999)
def test_exception_with_switch_depth2(self): from _continuation import continulet # def depth2(c): seen.append(4) c.switch() seen.append(6) raise ValueError # def depth1(c): seen.append(1) c.switch() seen.append(3) c2 = continulet(depth2) c2.switch() seen.append(5) raises(ValueError, c2.switch) assert not c2.is_pending() seen.append(7) assert c.is_pending() raise KeyError # seen = [] c = continulet(depth1) c.switch() seen.append(2) raises(KeyError, c.switch) assert not c.is_pending() assert seen == [1, 2, 3, 4, 5, 6, 7]
def test_copy_continulet_not_started_multiple(self): from _continuation import continulet, error import copy lst = [] co = continulet(lst.append) co2, lst2 = copy.deepcopy((co, lst)) co3, lst3 = copy.deepcopy((co, lst)) co4, lst4 = copy.deepcopy((co, lst)) # assert lst == [] co.switch() assert lst == [co] # assert lst2 == [] co2.switch() assert lst2 == [co2] # assert lst3 == [] co3.switch() assert lst3 == [co3] # assert lst4 == [] co4.switch() assert lst4 == [co4]
def test_f_back(self): import sys from _continuation import continulet # def bar(c): c.switch(sys._getframe(0)) c.switch(sys._getframe(0).f_back) c.switch(sys._getframe(1)) c.switch(sys._getframe(1).f_back) assert sys._getframe(2) is f3_foo.f_back c.switch(sys._getframe(2)) def foo(c): bar(c) # c = continulet(foo) f1_bar = c.switch() assert f1_bar.f_code.co_name == 'bar' f2_foo = c.switch() assert f2_foo.f_code.co_name == 'foo' f3_foo = c.switch() assert f3_foo is f2_foo assert f1_bar.f_back is f3_foo def main(): f4_main = c.switch() assert f4_main.f_code.co_name == 'main' assert f3_foo.f_back is f1_bar # not running, so a loop def main2(): f5_main2 = c.switch() assert f5_main2.f_code.co_name == 'main2' assert f3_foo.f_back is f1_bar # not running, so a loop main() main2() res = c.switch() assert res is None assert f3_foo.f_back is None
def test_switch2_not_initialized(self): from _continuation import continulet c0 = continulet.__new__(continulet) c0bis = continulet.__new__(continulet) res = c0.switch(123, to=c0) assert res == 123 res = c0.switch(123, to=c0bis) assert res == 123 raises(ValueError, c0.throw, ValueError, to=c0) raises(ValueError, c0.throw, ValueError, to=c0bis) # def f1(c1): c1.switch('a') raises(ValueError, c1.switch, 'b') raises(KeyError, c1.switch, 'c') return 'd' c1 = continulet(f1) res = c0.switch(to=c1) assert res == 'a' res = c1.switch(to=c0) assert res == 'b' res = c1.throw(ValueError, to=c0) assert res == 'c' res = c0.throw(KeyError, to=c1) assert res == 'd'
def test_traceback_is_complete(self): import sys from _continuation import continulet # def g(): raise KeyError def f(c): g() # def do(c): c.switch() # c = continulet(f) try: do(c) except KeyError: tb = sys.exc_info()[2] else: raise AssertionError("should have raised!") # assert tb.tb_next.tb_frame.f_code.co_name == 'do' assert tb.tb_next.tb_next.tb_frame.f_code.co_name == 'f' assert tb.tb_next.tb_next.tb_next.tb_frame.f_code.co_name == 'g' assert tb.tb_next.tb_next.tb_next.tb_next is None
def test_new_empty(self): from _continuation import continulet # def empty_callback(c): never_called # c = continulet(empty_callback) assert type(c) is continulet
def test_bug_issue1984(self): from _continuation import continulet, error c1 = continulet.__new__(continulet) c2 = continulet(lambda g: None) continulet.switch(c1, to=c2) raises(error, continulet.switch, c1, to=c2)
def test_switch2_immediately_away_corner_case(self): from _continuation import continulet # def f1(c1): this_is_never_seen # def f2(c2): res = c2.switch('z') assert res is None return 'b' # this goes back into the caller, which is f1, # but f1 didn't start yet, so a None-value value # has nowhere to go to... c1 = continulet(f1) c2 = continulet(f2) res = c2.switch() assert res == 'z' raises(TypeError, c1.switch, to=c2) # "can't send non-None value"
def test_throw_to_starting(self): from _continuation import continulet # def f1(c1): not_reached # c1 = continulet(f1) raises(IndexError, c1.throw, IndexError)
def test_basic_setup(self): from _continuation import continulet lst = [4] co = continulet(lst.append) assert lst == [4] res = co.switch() assert res is None assert lst == [4, co]
def test_no_double_init(self): from _continuation import continulet, error # def empty_callback(c1): never_called # c = continulet(empty_callback) raises(error, c.__init__, empty_callback)
def test_no_init_after_finished(self): from _continuation import continulet, error # def empty_callback(c1): return 42 # c = continulet(empty_callback) res = c.switch() assert res == 42 raises(error, c.__init__, empty_callback)
def test_throw2_no_op(self): from _continuation import continulet # def f1(c1): raises(ValueError, c1.throw, ValueError, to=c1) return "ok" # c1 = continulet(f1) res = c1.switch() assert res == "ok"
def test_continuation_error(self): from _continuation import continulet, error # def empty_callback(c): return 42 # c = continulet(empty_callback) c.switch() e = raises(error, c.switch) assert str(e.value) == "continulet already finished"
def test_switch2_no_op(self): from _continuation import continulet # def f1(c1): res = c1.switch('a', to=c1) assert res == 'a' return 42 # c1 = continulet(f1) res = c1.switch() assert res == 42
def test_throw2_simple(self): from _continuation import continulet # def f1(c1): not_reached def f2(c2): try: c2.switch("ready") except IndexError: raise ValueError # c1 = continulet(f1) c2 = continulet(f2) res = c2.switch() assert res == "ready" assert c1.is_pending() assert c2.is_pending() raises(ValueError, c1.throw, IndexError, to=c2) assert not c1.is_pending() assert not c2.is_pending()
def test_f_back(self): import sys from _continuation import continulet stack = self.stack # def bar(c): assert stack() == ['bar', 'foo', 'test_f_back'] c.switch(sys._getframe(0)) c.switch(sys._getframe(0).f_back) c.switch(sys._getframe(1)) # assert stack() == ['bar', 'foo', 'main', 'test_f_back'] c.switch(sys._getframe(1).f_back) # assert stack() == ['bar', 'foo', 'main2', 'test_f_back'] assert sys._getframe(2) is f3_foo.f_back c.switch(sys._getframe(2)) def foo(c): bar(c) # assert stack() == ['test_f_back'] c = continulet(foo) f1_bar = c.switch() assert f1_bar.f_code.co_name == 'bar' f2_foo = c.switch() assert f2_foo.f_code.co_name == 'foo' f3_foo = c.switch() assert f3_foo is f2_foo assert f1_bar.f_back is f3_foo # def main(): f4_main = c.switch() assert f4_main.f_code.co_name == 'main' assert f3_foo.f_back is f1_bar # not running, so a loop assert stack() == ['main', 'test_f_back'] assert stack(f1_bar) == ['bar', 'foo', '...'] # def main2(): f5_main2 = c.switch() assert f5_main2.f_code.co_name == 'main2' assert f3_foo.f_back is f1_bar # not running, so a loop assert stack(f1_bar) == ['bar', 'foo', '...'] # main() main2() res = c.switch() assert res is None assert f3_foo.f_back is None