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

AsyncGenerator/AsyncIterable do not work with overloaded async def #14996

Closed
gwax opened this issue Apr 2, 2023 · 1 comment · Fixed by #14998
Closed

AsyncGenerator/AsyncIterable do not work with overloaded async def #14996

gwax opened this issue Apr 2, 2023 · 1 comment · Fixed by #14998
Labels
bug mypy got something wrong topic-async async, await, asyncio

Comments

@gwax
Copy link

gwax commented Apr 2, 2023

Bug Report

When using typing.overload with an async function that returns an AsyncGenerator or AsyncIterable, the overloads fail with Overloaded function implementation cannot produce return type of signature # when defined using async def

To Reproduce

Failure case: https://mypy-play.net/?mypy=latest&python=3.11&gist=f9b64edbf09acd4b1952f5753669c2e7

from typing import AsyncGenerator, overload

@overload
async def foo(*, a: int) -> AsyncGenerator[int, None]:
    ...
    
@overload
async def foo(*, b: int) -> AsyncGenerator[int, None]:
    ...

async def foo(*, a: int | None = None, b: int | None = None) -> AsyncGenerator[int, None]:
    if a is not None:
        for i in range(a):
            yield i
    elif b is not None:
        for i in range(b):
            yield i
    else:
        yield -1

Unexpected success case: https://mypy-play.net/?mypy=latest&python=3.11&gist=2fcc9c2372664f4ce257a9cec2849698

from typing import AsyncGenerator, overload

@overload
def foo(*, a: int) -> AsyncGenerator[int, None]:
    ...
    
@overload
def foo(*, b: int) -> AsyncGenerator[int, None]:
    ...

async def foo(*, a: int | None = None, b: int | None = None) -> AsyncGenerator[int, None]:
    if a is not None:
        for i in range(a):
            yield i
    elif b is not None:
        for i in range(b):
            yield i
    else:
        yield -1

Expected Behavior

no errors when overloads are also defined with async def and error when overloads are defined with def

Actual Behavior

when overloads are defined with async def:

main.py:11: error: Overloaded function implementation cannot produce return type of signature 1  [misc]
main.py:11: error: Overloaded function implementation cannot produce return type of signature 2  [misc]
Found 2 errors in 1 file (checked 1 source file)

when overloads are defined with def: no errors

Your Environment

  • Mypy version used: 1.1.1 (mypy-play)
  • Python version used: 3.11 (mypy-play)
@gwax gwax added the bug mypy got something wrong label Apr 2, 2023
@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Apr 2, 2023

Your success case is expected and is the recommend thing to do. I just added some more documentation for this last week in #14973, see https://mypy.readthedocs.io/en/latest/more_types.html#asynchronous-iterators

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-async async, await, asyncio
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants