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

PLE1142 false & missed alarms #14167

Closed
jakkdl opened this issue Nov 7, 2024 · 2 comments · Fixed by #14218
Closed

PLE1142 false & missed alarms #14167

jakkdl opened this issue Nov 7, 2024 · 2 comments · Fixed by #14218
Assignees
Labels
bug Something isn't working

Comments

@jakkdl
Copy link

jakkdl commented Nov 7, 2024

def foo():
    ...

def should_not_give_PLE1142():
    (await x for x in foo())

def should_give_PLE1142():
    # note the list comprehension
    [x async for x in foo()]

# these latter two are correctly handled
def correctly_gives_PLE1142():
    (x for x in await foo())

def correctly_does_not_give_PLE1142():
    (x async for x in foo())

output:

$ ruff check --select=PLE1142 --isolated ruff_bug.py 
ruff_bug.py:5:6: PLE1142 `await` should be used within an async function
ruff_bug.py:12:17: PLE1142 `await` should be used within an async function
ruff_bug.py:13:6: PLE1142 `await` should be used within an async function
$ ruff --version
ruff 0.3.7

it should error on 9, 12 and 13.

Generator expressions only immediately evaluate the target, so the other fields do not need to be validated. And you appear to have missed async for completely for this check, but make sure to not enable that for generator expressions.
If you don't want to take my word for it or go dig through PEPs you can verify this by simply trying to let python parse the file, it will give a SyntaxError for 9/12/13 (though it abandons parsing the file on first error so you'll need to progressively comment out stuff to check)

@charliermarsh
Copy link
Member

Sorry to ask this, but for my understanding, can you illustrate why the first one shouldn't flag with a more complete example?

@jakkdl
Copy link
Author

jakkdl commented Nov 8, 2024

Sorry to ask this, but for my understanding, can you illustrate why the first one shouldn't flag with a more complete example?

no problem! Throwing in async for in genexp in sync func as well :)

import asyncio
from collections.abc import AsyncIterable, Awaitable

async def awaitable_func(x: int) -> int:
    return x

def await_in_genexp_in_sync() -> AsyncIterable[int]:
    return (await awaitable_func(x) for x in range(3))

def async_for_in_genexp_in_sync() -> AsyncIterable[Awaitable[int]]:
    return (awaitable_func(x) async for x in await_in_genexp_in_sync())

async def main():
    async for i in await_in_genexp_in_sync():
        print(i)
    async for i in async_for_in_genexp_in_sync():
        print(await i)

asyncio.run(main())
$ python --version
Python 3.12.4
$ python genexp_example.py
a 0
a 1
a 2
b 0
b 1
b 2

note that mypy will complain with await-not-async on this python/mypy#18124, but pyright handles it (though current version also misses errors microsoft/pyright#9414)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants