Brad Solomon
Brad Solomon

Reputation: 40918

Using mypy with await

Consider the following basic script using asyncio/async/await:

import asyncio
from typing import List

async def foo(x) -> int:
    await asyncio.sleep(x / 2)
    return x

async def main() -> List[int]:
    return await asyncio.gather(*(foo(i) for i in (1, 2, 3)))

if __name__ == "__main__":
    print(asyncio.run(main()))

This runs find, printing [1, 2, 3]; await asyncio.gather() produces a List[int].

However, mypy does not like this file; it raises:

mypytest.py:9: error:

Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "List[int]")

I'm assuming that's because of the asyncio.gather() annotations in typeshed.

However, this is still a bit confusing from a user perspective. What can I be doing differently here to make mypy happy? Why does this ambiguity exist?


For what it's worth, there's not much on this in the Typing async/await part of the mypy docs.

Upvotes: 2

Views: 3262

Answers (2)

Brad Solomon
Brad Solomon

Reputation: 40918

This discrepancy was addressed in commit 412b9e7 to the typeshed repository, which added a final @overload to account for the potential List result.

Upvotes: 1

Markus Unterwaditzer
Markus Unterwaditzer

Reputation: 8244

Either annotate that line with # type: ignore or cast to list again:

return list(await asyncio.gather(*(foo(i) for i in (1, 2, 3))))

Upvotes: -1

Related Questions