Glossary

cancel scope

A cancel scope is a context manager which can request the library cancels whatever task is executing in the body of the with (or async with) block. A cancel scope is the key component of a timeout context, and used in TaskGroups / Nurseries to cancel any remaining child tasks if one raises an exception.

timeout context

A context manager that enforces a timeout on a block of code, by cancelling it after a specified duration or at a preset time. The timeout can also be rescheduled after creation. They are internally implemented with a cancel scope, which in anyio & trio can be directly initialized with a deadline.

TaskGroup / Nursery

A collection of child Tasks that can run concurrently. Internally contains a cancel scope for canceling any remaining child tasks if one raises an exception.

Cancelled / CancelledError

Handling cancellation is very sensitive, and you generally never want to catch a cancellation exception without letting it propagate to the library.

General documentation on cancellation in the different async libraries:

Exception classes:

Checkpoint

Checkpoints are points where the async backend checks for cancellation and can switch which task is running, in an await, async for, or async with expression. Regular checkpoints can be important for both performance and correctness.

Trio has extensive and detailed documentation on the concept of checkpoints, and guarantees that all async functions defined by Trio will either checkpoint or raise an exception when await-ed. async for on Trio iterables will checkpoint before each iteration, and when exhausting the iterator, and async with will checkpoint on at least one of enter/exit.

The one exception is trio.open_nursery() and anyio.create_task_group(). They do not checkpoint on entry, and on exit they insert a schedule point. However, if sub-tasks are cancelled they will be propagated on exit, so if you’re starting tasks you can usually treat the exit as a cancel point.

asyncio does not place any guarantees on if or when asyncio functions will checkpoint. This means that enabling and adhering to ASYNC91x will still not guarantee checkpoints on asyncio (even if used via anyio).

When using Trio (or an AnyIO library that people might use on Trio), it can be very helpful to ensure that your own code adheres to the same guarantees as Trio. For this we supply the ASYNC91x rules. To make it possible to reason the rules will also assume that all other async functions also adhere to those rules. This means you must be careful if you’re using 3rd-party async libraries.

To insert a checkpoint with no other side effects, you can use trio.lowlevel.checkpoint()/anyio.lowlevel.checkpoint()/asyncio.sleep(0)

Schedule Point

A schedule point is half of a full Checkpoint, which allows the async backend to switch the running task, but doesn’t check for cancellation (the other half is a Cancel Point). While you are unlikely to need one, they are available as trio.lowlevel.cancel_shielded_checkpoint()/anyio.lowlevel.cancel_shielded_checkpoint(), and equivalent to

from trio import CancelScope, lowlevel
# or
# from anyio import CancelScope, lowlevel

with CancelScope(shield=True):
    await lowlevel.checkpoint()

asyncio does not have any direct equivalents due to their cancellation model being different.

Cancel Point

A schedule point is half of a full Checkpoint, which will raise Cancelled / CancelledError if the enclosing cancel scope has been cancelled, but does not allow the scheduler to switch to a different task (the other half is a Schedule Point). While you are unlikely to need one, they are available as trio.lowlevel.checkpoint_if_cancelled()/anyio.lowlevel.checkpoint_if_cancelled(). Users of asyncio might want to use asyncio.Task.cancelled().

Channel / Stream / Queue

Interfaces used for communicating between tasks, processes, the network, etc.