juanignaciosl
juanignaciosl

Reputation: 3573

How can I use mypy when overriding coroutine of supertypes?

There's one class that extends another and overrides a coroutine that returns an iterator:

class Repository:
     async def run(self, query: Query) -> AsyncIterator[int]:
...

class MyRepository(Repository):
     async def run(self, query: Query) -> AsyncIterator[int]:
...

Running mypy returns this error:

error: Return type "AsyncIterator[int]" of "run" incompatible with return type "Coroutine[Any, Any, AsyncIterator[int]]" in supertype "Repository"

Coroutines are typed like normal functions, so I'm not sure what the right approach is.

Using ABC classes won't fix it:

class Repository(metaclass=ABCMeta):
    @abstractmethod
    async def run(self, query: Query) -> AsyncIterator[int]:

Upvotes: 4

Views: 1652

Answers (1)

juanignaciosl
juanignaciosl

Reputation: 3573

Found it thanks to this issue:

I think you shouldn't make the protocol function async def, but just def. Conceptually, an async generator is a callable that returns an AsyncIterator (or more precisely, an AsyncGenerator). But an async def function without a yield returns an Awaitable of whatever its declared return type is, so that's how mypy interprets your protocol.

So, changing async def run with def run works.

Upvotes: 7

Related Questions