Skip to content

Instantly share code, notes, and snippets.

@nakamuray
Created May 24, 2016 11:49
Show Gist options
  • Save nakamuray/c122727694fdd946cb471a74f73bc7bd to your computer and use it in GitHub Desktop.
Save nakamuray/c122727694fdd946cb471a74f73bc7bd to your computer and use it in GitHub Desktop.
re-implement asyncio.coroutine like something
import asyncio
import functools
import types
def my_coroutine(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
result_fut = asyncio.Future()
gen = func(*args, **kwargs)
assert isinstance(gen, types.GeneratorType)
next_fut = next(gen)
assert isinstance(next_fut, asyncio.Future)
def _callback(fut):
result = fut.result()
if isinstance(result, asyncio.Future):
result.add_done_callback(result_fut)
return
try:
next_fut = gen.send(result)
except StopIteration as e:
result_fut.set_result(e.value)
else:
assert isinstance(next_fut, asyncio.Future)
next_fut.add_done_callback(_callback)
next_fut.add_done_callback(_callback)
return result_fut
return wrapper
def test():
@my_coroutine
def sleep_and_done():
print(3)
yield from asyncio.sleep(1)
print(2)
yield from asyncio.sleep(1)
print(1)
yield from asyncio.sleep(1)
print('done')
return 42
loop = asyncio.get_event_loop()
result = loop.run_until_complete(sleep_and_done())
assert result == 42
@my_coroutine
def coroutine_within_coroutine():
result = yield from sleep_and_done()
print(result)
loop = asyncio.get_event_loop()
result = loop.run_until_complete(coroutine_within_coroutine())
assert result is None
if __name__ == '__main__':
test()
@nakamuray
Copy link
Author

その後色々調べた結果、これは asyncio.tasks.Task のような何かっぽい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment