Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return type AsyncIterable not correctly deduced for abstract methods #17188

Closed
MaxG87 opened this issue Apr 29, 2024 · 2 comments
Closed

Return type AsyncIterable not correctly deduced for abstract methods #17188

MaxG87 opened this issue Apr 29, 2024 · 2 comments
Labels
bug mypy got something wrong

Comments

@MaxG87
Copy link

MaxG87 commented Apr 29, 2024

Bug Report

I am trying to write an abstract class (Protocol or abc.ABC) with a method that yields values. This concept works well for def foo(self, args: list[T]) -> Iterable[T]: ..., but breaks down for async def foo(self, args: list[T]) -> AsyncIterable[T]: .... If yield is added to the body of the async method, the return type is correctly deduced.

In order to make the issue self documenting, I add a snippet from the playground example:

import abc
import typing as t


class MyABC(abc.ABC):
    # Putting `yield` instead of `...` in the body would cure the error.
    @abc.abstractmethod
    async def get_strings(self, strings: list[str]) -> t.AsyncIterable[str]: ...


class MyImplementation(MyABC):
    async def get_strings(self, strings: list[str]) -> t.AsyncIterable[str]:
        for string in strings:
            yield string

The error is error: Return type "AsyncIterable[str]" of "get_strings" incompatible with return type "Coroutine[Any, Any, AsyncIterable[str]]" in supertype "MyABC" [override]

To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=86f6de6b39e17f87e2c4e46b01aaebc2

Expected Behavior

No error, even without yield.

Actual Behavior

The error is error: Return type "AsyncIterable[str]" of "get_strings" incompatible with return type "Coroutine[Any, Any, AsyncIterable[str]]" in supertype "MyABC" [override]

Your Environment
The error is reproduced on mypy 1.10 on the Playground.

edit: I found #5385 which describes a very similar problem, maybe the same even. However, I am not too convinced with the proposed solution. I think it should be possible to write a Protocol or abc.ABC just the way I would write a normal function.

@MaxG87 MaxG87 added the bug mypy got something wrong label Apr 29, 2024
@MaxG87
Copy link
Author

MaxG87 commented Apr 29, 2024

Using the remark in #5385, a "fixed" protocol would look like this:

import abc
import typing as t


class MyABC(abc.ABC):
     @abc.abstractmethod
    def get_strings(self, strings: list[str]) -> t.AsyncIterable[str]: ...


class MyImplementation(MyABC):
    async def get_strings(self, strings: list[str]) -> t.AsyncIterable[str]:
        for string in strings:
            yield string

(playground)

I still find this unfortunate, though. However, maybe this is a rough edge that has to be accepted.

@JelleZijlstra
Copy link
Member

As you say, a duplicate of #5385.

@JelleZijlstra JelleZijlstra closed this as not planned Won't fix, can't repro, duplicate, stale Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants