pythonpython-asynciopython-typingcoroutine

The right way to type hint a Coroutine function?


I cannot wrap my head around type hinting a Coroutine. As far as I understand, when we declare a function like so:

async def some_function(arg1: int, arg2: str) -> list:
    ...

we effectively declare a function, which returns a coroutine, which, when awaited, returns a list. So, the way to type hint it would be:

f: Callable[[int, str], Coroutine[???]] = some_function

But Coroutine generic type has 3 arguments! We can see it if we go to the typing.py file:

...
Coroutine = _alias(collections.abc.Coroutine, 3)
...

There is also Awaitable type, which logically should be a parent of Coroutine with only one generic parameter (the return type, I suppose):

...
Awaitable = _alias(collections.abc.Awaitable, 1)
...

So maybe it would be more or less correct to type hint the function this way:

f: Callable[[int, str], Awaitable[list]] = some_function

Or is it?

So, basically, the questions are:

  1. Can one use Awaitable instead of Coroutine in the case of type hinting an async def function?
  2. What are the correct parameters for the Coroutine generic type and what are its use-cases?

Solution

  • As the docs state:

    Coroutine objects and instances of the Coroutine ABC are all instances of the Awaitable ABC.

    And for the Coroutine type:

    A generic version of collections.abc.Coroutine. The variance and order of type variables correspond to those of Generator.

    Generator in turn has the signature Generator[YieldType, SendType, ReturnType]. So if you want to preserve that type information, use Coroutine, otherwise Awaitable should suffice.