The problem here is that if we don’t yield to the event loop, or if we allow all-sync context managers, this breaks the syntactic visibility of checkpoints.
Trio goes to considerable lengths to ensure that every time you see the await, async for, or async with keyword, it’s executing a checkpoint where the event loop has a chance to cancel the task or schedule other work[1]. This is vital to avoid deadlocks in a cooperative-concurrency system; I wrote a whole linter and Anthropic’s codebase puts considerable effort into maintaining this property.
or raises an exception; the
__aexit__of a nursery also has slightly more complicated rules ↩︎