Skip to content

ASYNC910/911: require only one of __aenter__/__aexit__ to contain a checkpoint #441

@Zac-HD

Description

@Zac-HD

Per https://trio.readthedocs.io/en/stable/reference-core.html#checkpoints

  • If you call an async function provided by Trio (await <something in trio>), and it doesn’t raise an exception, then it always acts as a checkpoint. (If it does raise an exception, it might act as a checkpoint or might not.)
    • ...
    • Partial exception for async context managers: Both the entry and exit of an async with block are defined as async functions; but for a particular type of async context manager, it’s often the case that only one of them is able to block, which means only that one will act as a checkpoint.

So, we should not complain about missing checkpoints when they are part of an async context manager which does checkpoint in the other part. For example:

import trio

class CtxWithSetup:
    async def __aenter__(self):
        await trio.lowlevel.checkpoint()  # whatever slow setup

    async def __aexit__(self, exc_type, exc, tb):
        print(f"logging {exc=}")

class CtxWithTeardown:
    async def __aenter__(self):
        print(f"setup is quick")

    async def __aexit__(self, exc_type, exc, tb):
        await trio.lowlevel.checkpoint()  # whatever slow teardown

I wouldn't worry about inherited methods for now; we can handle those if someone requests them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rule improvementImprovement for currently existing rule

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions