OSDir


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] Implementing an awaitable


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())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20181107/e2f7ee2d/attachment.html>