1# cython: language_level=3, binding=True 2# mode: run 3# tag: pep492, asyncfor, await 4 5 6def run_async(coro, ignore_type=False): 7 if not ignore_type: 8 #assert coro.__class__ is types.GeneratorType 9 assert coro.__class__.__name__ in ('coroutine', 'GeneratorWrapper'), coro.__class__.__name__ 10 11 buffer = [] 12 result = None 13 while True: 14 try: 15 buffer.append(coro.send(None)) 16 except StopIteration as ex: 17 result = ex.args[0] if ex.args else None 18 break 19 return buffer, result 20 21 22def run_async__await__(coro): 23 assert coro.__class__.__name__ in ('coroutine', 'GeneratorWrapper'), coro.__class__.__name__ 24 aw = coro.__await__() 25 buffer = [] 26 result = None 27 i = 0 28 while True: 29 try: 30 if i % 2: 31 buffer.append(next(aw)) 32 else: 33 buffer.append(aw.send(None)) 34 i += 1 35 except StopIteration as ex: 36 result = ex.args[0] if ex.args else None 37 break 38 return buffer, result 39 40 41async def await_pyobject(awaitable): 42 """ 43 >>> async def simple(): 44 ... return 10 45 46 >>> buffer, result = run_async(await_pyobject(simple())) 47 >>> result 48 10 49 50 >>> async def awaiting(awaitable): 51 ... return await awaitable 52 53 >>> buffer, result = run_async(await_pyobject(awaiting(simple()))) 54 >>> result 55 10 56 """ 57 return await awaitable 58 59 60def await_cyobject(): 61 """ 62 >>> async def run_await(awaitable): 63 ... return await awaitable 64 65 >>> simple, awaiting = await_cyobject() 66 67 >>> buffer, result = run_async(run_await(simple())) 68 >>> result 69 10 70 71 >>> buffer, result = run_async(run_await(awaiting(simple()))) 72 >>> result 73 10 74 75 >>> buffer, result = run_async(run_await(awaiting(awaiting(simple())))) 76 >>> result 77 10 78 79 >>> buffer, result = run_async(run_await(awaiting(run_await(awaiting(simple()))))) 80 >>> result 81 10 82 """ 83 84 async def simple(): 85 return 10 86 87 async def awaiting(awaitable): 88 return await awaitable 89 90 return simple, awaiting 91 92 93cimport cython 94 95def yield_from_cyobject(): 96 """ 97 >>> async def py_simple_nonit(): 98 ... return 10 99 100 >>> async def run_await(awaitable): 101 ... return await awaitable 102 103 >>> def run_yield_from(it): 104 ... return (yield from it) 105 106 >>> simple_nonit, simple_it, awaiting, yield_from = yield_from_cyobject() 107 108 >>> buffer, result = run_async(run_await(simple_it())) 109 >>> result 110 10 111 >>> buffer, result = run_async(run_await(awaiting(simple_it()))) 112 >>> result 113 10 114 >>> buffer, result = run_async(awaiting(run_await(simple_it())), ignore_type=True) 115 >>> result 116 10 117 >>> buffer, result = run_async(run_await(py_simple_nonit())) 118 >>> result 119 10 120 121 >>> buffer, result = run_async(run_yield_from(awaiting(run_await(simple_it()))), ignore_type=True) 122 >>> result 123 10 124 125 >>> buffer, result = run_async(run_yield_from(simple_it()), ignore_type=True) 126 >>> result 127 10 128 >>> buffer, result = run_async(yield_from(simple_it()), ignore_type=True) 129 >>> result 130 10 131 132 >>> next(run_yield_from(simple_nonit())) # doctest: +ELLIPSIS 133 Traceback (most recent call last): 134 TypeError: ... 135 >>> next(run_yield_from(py_simple_nonit())) # doctest: +ELLIPSIS 136 Traceback (most recent call last): 137 TypeError: ... 138 >>> next(yield_from(py_simple_nonit())) 139 Traceback (most recent call last): 140 TypeError: 'coroutine' object is not iterable 141 """ 142 async def simple_nonit(): 143 return 10 144 145 @cython.iterable_coroutine 146 async def simple_it(): 147 return 10 148 149 @cython.iterable_coroutine 150 async def awaiting(awaitable): 151 return await awaitable 152 153 def yield_from(it): 154 return (yield from it) 155 156 return simple_nonit, simple_it, awaiting, yield_from 157