1
votes

From the web, it says

When you have an asynchronous function (coroutine) in Python, you declare it with async def, which changes how its call behaves. In particular, calling it will immediately return a coroutine object, which basically says "I can run the coroutine with the arguments you called with and return a result when you await me"

So when you call an async function without await, you will get back a coroutine.

Why I get back a coroutine, why not just a generator? Because I'm not sending any future input to it.

1
It's defined better in PEP 3156.dirn
The confusing part is that the word coroutine is now used for two related but distinct concepts: one are the bidirectional generators defined in PEP 342, and the other are async functions defined in PEP 492. Calling an async function without awaiting it gives you a PEP 492 coroutine.user4815162342

1 Answers

1
votes

When coroutines first appeared in Python 3.4 they were implemented using generators:

import asyncio
from typing import Generator


@asyncio.coroutine
def test1():
    pass


assert isinstance(test1(), Generator)

It wasn't because coroutines always should be generators, it just happened they were: it was the most convenient way to implement them.


Starting with Python 3.5 coroutines got their new syntax async def/await which both cleaner and also helps to distinguish abstraction (coroutine) from its implementation detail (generator).

It seems that new-style coroutines were also patched to show that they shouldn't be treated like generators:

async def test2():
    pass


assert not isinstance(test2(), Generator)

So long story short: forget about generators when deal with coroutines. If you work with asyncio's abstractions like coroutines you should work with them rather than with their implementation details.