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

cannot apply @asynccontextmanager to a function that uses TypeVarTuple #17278

Closed
ZeeD opened this issue May 23, 2024 · 2 comments · Fixed by #17431
Closed

cannot apply @asynccontextmanager to a function that uses TypeVarTuple #17278

ZeeD opened this issue May 23, 2024 · 2 comments · Fixed by #17431
Labels
bug mypy got something wrong topic-pep-646 PEP 646 (TypeVarTuple, Unpack)

Comments

@ZeeD
Copy link

ZeeD commented May 23, 2024

I think this is a bug in mypy.
mypy-play.net

I want to properly annotate a generic async context manager to preserve the types of the *args in the returned value.

Ts = TypeVarTuple('Ts')

@asynccontextmanager
async def fun(*args: *Ts) -> AsyncIterator[tuple[*Ts]]:
    ...

but this snippet generate the following error

main.py:11: error: Argument 1 to "asynccontextmanager" has incompatible type "Callable[[VarArg(*Ts)], AsyncIterator[tuple[*Ts]]]"; expected "Callable[[VarArg(Never), KwArg(Never)], AsyncIterator[Never]]"  [arg-type]

The function types - without the @asynccontextmanager - seems to work correctly

@ZeeD ZeeD added the bug mypy got something wrong label May 23, 2024
@JelleZijlstra JelleZijlstra added the topic-pep-646 PEP 646 (TypeVarTuple, Unpack) label May 23, 2024
@sterliakov
Copy link
Contributor

Fun fact: don't use empty body for testing this, asynccontextmanager seems to reveal many independent bugs...

from contextlib import asynccontextmanager
from typing import AsyncIterator, TypeVarTuple

Ts = TypeVarTuple('Ts')

@asynccontextmanager  # E: Argument 1 to "asynccontextmanager" has incompatible type "Callable[[VarArg(*Ts)], AsyncIterator[tuple[*Ts]]]"; expected "Callable[[VarArg(Never), KwArg(Never)], AsyncIterator[Never]]"  [arg-type]
async def fun(*args: *Ts) -> AsyncIterator[tuple[*Ts]]:
    yield args
    

@asynccontextmanager  # E: Argument 1 to "asynccontextmanager" has incompatible type "Callable[[int], Coroutine[Any, Any, AsyncIterator[int]]]"; expected "Callable[[int], AsyncIterator[Never]]"  [arg-type]
async def int_bad(arg: int) -> AsyncIterator[int]:  # E: Missing return statement  [empty-body]
    ...


@asynccontextmanager
async def int_good(arg: int) -> AsyncIterator[int]:
    yield arg

Compare int_bad and int_good. missing-body error apparently breaks unnesting double "async-ness" of async def ... -> AsyncIterator[...].

Playground

@sterliakov
Copy link
Contributor

#17340 seems to be related.

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-pep-646 PEP 646 (TypeVarTuple, Unpack)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants