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

false "not async iterable" on use of overload with async iterable #10301

Closed
belm0 opened this issue Apr 8, 2021 · 5 comments
Closed

false "not async iterable" on use of overload with async iterable #10301

belm0 opened this issue Apr 8, 2021 · 5 comments
Labels
bug mypy got something wrong

Comments

@belm0
Copy link

belm0 commented Apr 8, 2021

Bug Report

Using typing.overload on an async iterator doesn't behave as I expected:

@overload
async def transitions(self, value: T) -> AsyncIterator[Tuple[T, T]]: ...
@overload
async def transitions(self, predicate: P) -> AsyncIterator[Tuple[T, T]]: ...
async def transitions(self, value_or_predicate):
    # impl with yield ...

if I remove async qualifier on the overloads, it appears to work. But that doesn't seem right...

Expected Behavior

no errors on correct usage

Actual Behavior

error on usage:

error: "Coroutine[Any, Any, AsyncIterator[Tuple[str, str]]]" has no attribute "__aiter__" (not async iterable)  [attr-defined]

Your Environment

  • Mypy version used: .812
  • Python version used: 3.7.7
@belm0 belm0 added the bug mypy got something wrong label Apr 8, 2021
@hauntsaninja
Copy link
Collaborator

That's kind of unfortunate. Removing the "async" from the overloads is probably your best solution, see #5385 (comment) for some more context

@belm0
Copy link
Author

belm0 commented Apr 8, 2021

Removing the async qualifier from the overloads seems sure to catch some tools off guard (IDE, etc.).

The agreed-upon solution should be clearly documented in the typing.overload / Protocol docs so that everyone has a standard reference.

@belm0
Copy link
Author

belm0 commented Jun 8, 2021

Removing the async qualifier now also confuses pylint: pylint-dev/astroid#1015

@dm9pZCAq
Copy link

i think this is related to this issue

code:

from abc import ABC, abstractmethod
from typing import Any, AsyncIterator


class MyABC(ABC):
    @abstractmethod
    async def func(self) -> AsyncIterator[Any]: pass


class MyClass(MyABC):
    async def func(self) -> AsyncIterator[Any]:
        yield 1

error:

test.py:11: error: Return type "AsyncIterator[Any]" of "func" incompatible with return type "Coroutine[Any, Any, AsyncIterator[Any]]" in supertype "MyABC"

@hauntsaninja as you can see in code example abstract and actual classes have the same func function signature, so i think #5385 (comment) is not fit into this example


  • Mypy version used: 0.931
  • Python version used: 3.9.9

@hauntsaninja
Copy link
Collaborator

They do not have the same type, because yield fundamentally changes what def does, so #5385 still applies. Feel free to replace pass with if False: yield 1. Or remove the async qualifier.

Closing because while mypy's behaviour here is surprising, it is correct, and I don't see a better solution here.

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

3 participants