Skip to content

TRIO100 false positive with an async CM (already fixed in flake8-trio - ruff is out of date) #9934

@mikenerone

Description

@mikenerone

Ruff 0.2.1

The following snippet illustrates a TRIO100 false positive when the scope contains an async context manager. Note that this bug is already fixed in flake8-trio (in python-trio/flake8-async/pull/176 I think). It's probably worth checking whether ruff needs to port other more recent fixes, as well.

from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager

import trio

@asynccontextmanager
async def a_cm_can_start_a_nursery() -> AsyncGenerator[None]:
    async with trio.open_nursery() as nursery:
        nursery.start_soon(trio.sleep_forever)
        yield

async def main() -> None:
    # ↓↓↓↓↓ TRIO100 A `with trio.CancelScope(...):` context does not contain any `await` statements. This makes it pointless, as the timeout can only be triggered by a checkpoint.
    with trio.CancelScope() as cancel_scope:
        async with a_cm_can_start_a_nursery():
            try:
                pass # Pretend there's some real logic.
            finally:
                # Body exiting. For all I know, the CM has nursery like this one does. If so, I need it cancelled.
                cancel_scope.cancel()

trio.run(main)

The above is a valid case for a cancel scope with no explicit awaits in the body. Without the cancel(), this hangs forever instead of exiting.

Note: if I put an async for in the try:, it's even more obvious that this yields, but TRIO100 still triggers.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions