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

Async generators are detected as synchronous generators erroneously #17482

Open
abrahammurciano opened this issue Jul 4, 2024 · 1 comment
Open
Labels
bug mypy got something wrong

Comments

@abrahammurciano
Copy link

abrahammurciano commented Jul 4, 2024

Bug Report

Asynchronous generator comprehensions such as (1 for f in futures if await f) are detected by mypy as regular synchronous generators.

I found a similar issue #12924 that has has been resolved by #12925, where expressions like (await f for f in futures) were being detected as regular synchronous generators instead of async ones. It looks like the fix didn't take into consideration that the await could be in the condition of the comprehension.

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.12&gist=80e893739ab1a8f98fd786da84b7e209

import asyncio
from typing import Awaitable, AsyncGenerator

async def foo(*coros: Awaitable[None]) -> None:
    gen = (False for f in coros if not await f)
    # Revealed type is "typing.Generator[builtins.bool, None, None]"
    # Runtime type is 'async_generator'
    reveal_type(gen)
    return await anext(gen)
    
asyncio.run(foo(asyncio.sleep(1), asyncio.sleep(2)))

Expected Behavior

Mypy should reveal the type as typing.AsyncGenerator.

Actual Behavior

Mypy reveals the type as typing.Generator

Your Environment

  • Mypy version used: 1.10.1
  • Python version used: 3.12
@abrahammurciano abrahammurciano added the bug mypy got something wrong label Jul 4, 2024
@abrahammurciano
Copy link
Author

@jhance looking at your pull request, you only check the left experssion for await:

if any(e.is_async) or has_await_expression(e.left_expr):

but I believe the right experssion would have to be checked as well, is that right?

if any(e.is_async) or has_await_expression(e.left_expr) or any(has_await_expression(cond) for condlist in condlists for cond in condlist):

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

1 participant