def test_deep_recursion(): def fact(n, result=1): if n <= 1: returnValue(result) else: noreturn(fact(n - 1, n * result)) yield assert deferred_result(inlineCallbacks(fact)(1)) == 1 assert deferred_result(inlineCallbacks(fact)(10)) == safe_fact(10) with recursion_limit(100): with assert_not_raises(RuntimeError): # +10 is actually too high here as we probably already have some stuff on the stack, but just to be sure assert deferred_result(inlineCallbacks(fact)(110)) == safe_fact(110) # ...and now let's prove that the same (tail call optimizable) algorithm without noreturn will eat up the stack def normal_fact(n, result=1): if n <= 1: returnValue(result) else: return normal_fact(n - 1, n * result) with recursion_limit(100): with assert_raises(RuntimeError): normal_fact(110)
def test_without_flatten(): global FLATTEN FLATTEN = False NO(0, 'foo', 'bar') YES((), 'foo', 'foo') NO(0, (), 'whatev') YES((), (), ()) YES(('whatev', ), ANY, 'whatev') YES((('whatev', 'whatev'), ), ANY, ('whatev', 'whatev')) YES((), ('foo',), ('foo',)) NO(0, ('whatev',), ('whatev', 'whatev')) NO(0, ('whatev', 'whatev'), ('whatev',)) YES((('foo',), ), ANY, ('foo',)) YES(('foo',), (ANY,), ('foo',)) YES((), (IGNORE(ANY),), ('whatev',)) YES(('foo',), (ANY, IGNORE(ANY)), ('foo', 'whatev',)) YES((), (IGNORE(ANY), IGNORE(ANY)), ('whatev', 'whatev',)) YES(('foo', 'bar'), (ANY, ANY), ('foo', 'bar',)) YES((), ('foo', IGNORE(ANY)), ('foo', 'whatev',)) NO(0, ('foo', IGNORE(ANY)), ('WRONG', 'whatev',)) NO(1, ('foo', ANY), ('WRONG', 'whatev',)) YES((), ('foo', (IGNORE(ANY), )), ('foo', ('whatev', ))) YES((1, 2, 3), ('foo', (ANY, (ANY, (ANY, )))), ('foo', (1, (2, (3,))))) YES((2, 3), ('foo', (IGNORE(ANY), (ANY, (ANY, )))), ('foo', (1, (2, (3,))))) YES((3, ), ('foo', (IGNORE(ANY), (IGNORE(ANY), (ANY, )))), ('foo', (1, (2, (3,))))) with assert_not_raises(ValueError): _, (_, _, _) = match( ('foo', (ANY, (ANY, (ANY, )))), ('WRONG', (1, (2, (3,)))), flatten=False) with assert_not_raises(ValueError): _, _, _, _ = match( ('foo', (ANY, (ANY, (ANY, )))), ('WRONG', (1, (2, (3,)))), flatten=True)
def test_with_previous_yield_result_not_none(): class MockException(Exception): pass fn_called = [False] @inlineCallbacks def fn(): fn_called[0] = True try: yield fail(MockException()) except MockException: pass noreturn(fn2()) def fn2(): yield succeed(None) with assert_not_raises(MockException): fn() assert fn_called[0]
def test_without_flatten(): global FLATTEN FLATTEN = False NO(0, 'foo', 'bar') YES((), 'foo', 'foo') NO(0, (), 'whatev') YES((), (), ()) YES(('whatev', ), ANY, 'whatev') YES((('whatev', 'whatev'), ), ANY, ('whatev', 'whatev')) YES((), ('foo', ), ('foo', )) NO(0, ('whatev', ), ('whatev', 'whatev')) NO(0, ('whatev', 'whatev'), ('whatev', )) YES((('foo', ), ), ANY, ('foo', )) YES(('foo', ), (ANY, ), ('foo', )) YES((), (IGNORE(ANY), ), ('whatev', )) YES(('foo', ), (ANY, IGNORE(ANY)), ( 'foo', 'whatev', )) YES((), (IGNORE(ANY), IGNORE(ANY)), ( 'whatev', 'whatev', )) YES(('foo', 'bar'), (ANY, ANY), ( 'foo', 'bar', )) YES((), ('foo', IGNORE(ANY)), ( 'foo', 'whatev', )) NO(0, ('foo', IGNORE(ANY)), ( 'WRONG', 'whatev', )) NO(1, ('foo', ANY), ( 'WRONG', 'whatev', )) YES((), ('foo', (IGNORE(ANY), )), ('foo', ('whatev', ))) YES((1, 2, 3), ('foo', (ANY, (ANY, (ANY, )))), ('foo', (1, (2, (3, ))))) YES((2, 3), ('foo', (IGNORE(ANY), (ANY, (ANY, )))), ('foo', (1, (2, (3, ))))) YES((3, ), ('foo', (IGNORE(ANY), (IGNORE(ANY), (ANY, )))), ('foo', (1, (2, (3, ))))) with assert_not_raises(ValueError): _, (_, _, _) = match(('foo', (ANY, (ANY, (ANY, )))), ('WRONG', (1, (2, (3, )))), flatten=False) with assert_not_raises(ValueError): _, _, _, _ = match(('foo', (ANY, (ANY, (ANY, )))), ('WRONG', (1, (2, (3, )))), flatten=True)