I'm trying to figure out if our documentation on the new awaitable concept in Python 3.6+ is correct. It seems to imply that if an object's __await__ method returns an iterator, the object is awaitable. However, just returning an iterator doesn't seem to work with await in a coroutine or with the asyncio selector loop's run_until_complete method.
If the awaitable is not a coroutine or future, it looks like we wrap it in a coroutine using sub-generator delegation, and therefore have to have an iterator that fits a very specific shape for the coroutine step process that isn't documented anywhere I could find. Am I missing something? If the definition of an awaitable is more than just an __await__ iterator, we may need to expand the documentation as well as the abstract base class. Here's what I tried in making a synchronous awaitable that resolves to the int 42: class MyAwaitable(Awaitable): def __await__(self): return iter((42,)) # RuntimeError: Task got bad yield: 42 class MyAwaitable(Awaitable): def __await__(self): yield 42 # RuntimeError: Task got bad yield: 42 class MyAwaitable(Awaitable): def __await__(self): return (i for i in (42,)) # RuntimeError: Task got bad yield: 42 class MyAwaitable(Awaitable): def __await__(self): return self def __next__(self): return 42 # RuntimeError: Task got bad yield: 42''' class MyAwaitable(Awaitable): def __await__(self): return iter(asyncio.coroutine(lambda: 42)()) # TypeError: __await__() returned a coroutine class MyAwaitable(Awaitable): def __await__(self): yield from asyncio.coroutine(lambda: 42)() # None class MyAwaitable(Awaitable): def __await__(self): return (yield from asyncio.coroutine(lambda: 42)()) # 42 async def await_things(): print(await MyAwaitable()) asyncio.get_event_loop().run_until_complete(await_things())
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com