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())