Commit 9c5dca1b authored by Stefan Behnel's avatar Stefan Behnel

re-implement Coroutine.__await__() using a dedicated wrapper type to avoid...

re-implement Coroutine.__await__() using a dedicated wrapper type to avoid having to make a Coroutine half an Iterator
parent ef2f3011
This diff is collapsed.
# mode: run
# tag: asyncio
# tag: asyncio, pep492
"""
PYTHON setup.py build_ext -i
PYTHON test_from_import.py
PYTHON test_import.py
PYTHON test_async_def.py
PYTHON test_async_def_future.py
PYTHON test_all.py
"""
......@@ -63,6 +64,25 @@ if ASYNCIO_SUPPORTS_COROUTINE:
runloop(async_def.wait3)
######## test_async_def_future.py ########
import sys
ASYNCIO_SUPPORTS_COROUTINE = sys.version_info[:2] >= (3, 5)
if ASYNCIO_SUPPORTS_COROUTINE:
from async_def_future import await_future
import asyncio
def runloop():
loop = asyncio.get_event_loop()
task, events, expected = await_future(loop)
result = loop.run_until_complete(task())
assert events == expected, events
runloop()
######## test_all.py ########
import sys
......@@ -172,3 +192,27 @@ async def wait3():
await asyncio.sleep(0.01)
counter += 1
return counter
######## async_def_future.pyx ########
import asyncio
def await_future(loop):
events = []
async def worker():
fut = asyncio.Future()
def setval():
events.append('setval')
fut.set_result(123)
events.append('setup')
loop.call_later(0.2, setval)
events.append(await fut)
async def test():
await worker()
expected = ['setup', 'setval', 123]
return test, events, expected
......@@ -73,7 +73,7 @@ class AsyncYield:
def run_async(coro):
#assert coro.__class__ is types.GeneratorType
assert coro.__class__.__name__ in ('coroutine', 'GeneratorWrapper')
assert coro.__class__.__name__ in ('coroutine', 'GeneratorWrapper'), coro.__class__.__name__
buffer = []
result = None
......@@ -226,9 +226,8 @@ class CoroutineTest(unittest.TestCase):
with check():
iter(foo())
# in Cython: not iterable, but an iterator ...
#with check():
# next(foo())
with check():
next(foo())
with silence_coro_gc(), check():
for i in foo():
......@@ -306,6 +305,47 @@ class CoroutineTest(unittest.TestCase):
foo()
gc.collect()
def test_func_10(self):
N = 0
@types_coroutine
def gen():
nonlocal N
try:
a = yield
yield (a ** 2)
except ZeroDivisionError:
N += 100
raise
finally:
N += 1
async def foo():
await gen()
coro = foo()
aw = coro.__await__()
self.assertIs(aw, iter(aw))
next(aw)
self.assertEqual(aw.send(10), 100)
with self.assertRaises(TypeError):
type(aw).send(None, None)
self.assertEqual(N, 0)
aw.close()
self.assertEqual(N, 1)
with self.assertRaises(TypeError):
type(aw).close(None)
coro = foo()
aw = coro.__await__()
next(aw)
with self.assertRaises(ZeroDivisionError):
aw.throw(ZeroDivisionError, None, None)
self.assertEqual(N, 102)
with self.assertRaises(TypeError):
type(aw).throw(None, None, None, None)
def test_await_1(self):
async def foo():
......@@ -460,6 +500,20 @@ class CoroutineTest(unittest.TestCase):
run_async(foo())
def test_await_iterator(self):
async def foo():
return 123
coro = foo()
it = coro.__await__()
self.assertEqual(type(it).__name__, 'coroutine_await')
with self.assertRaisesRegex(TypeError, "cannot instantiate 'coroutine_await' type"):
type(it)() # cannot instantiate
with self.assertRaisesRegex(StopIteration, "123"):
next(it)
def test_with_1(self):
class Manager:
def __init__(self, name):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment