Asyncio task cancellation requests that a task raise CancelledError at a suspension point, allowing its finally cleanup to run.
Python concurrency interview: cancellation must still run cleanup
Operation contract
The owned worker signals that it has started, then waits on an event that the test never releases. The caller cancels it and awaits the result. Cleanup records a release marker before the caller observes CancelledError. No timing sleep is used to guess whether the worker reached its suspension point; the start event defines that boundary.
Failure and ownership boundary
Cancellation is cooperative. Code that blocks the event-loop thread or suppresses cancellation can violate the caller’s expectations. Releasing a local marker is not proof that an external service canceled a request. Python asyncio timeout: cancellation and cleanup ownership and Python asyncio TaskGroup: cancel sibling work and retain failure evidence address related caller/worker coordination.
Working program
import asyncio
async def inspect_cancellation():
started = asyncio.Event()
never_released = asyncio.Event()
cleanup = []
async def worker():
try:
started.set()
await never_released.wait()
finally:
cleanup.append("released")
task = asyncio.create_task(worker())
await started.wait()
task.cancel()
try:
await task
except asyncio.CancelledError:
print("caller observed cancellation")
print("cleanup:", cleanup)
print("task finished:", task.done())
asyncio.run(inspect_cancellation())Output
caller observed cancellation
cleanup: ['released']
task finished: TrueCosts and limits
The fixture owns one task and two event objects. Cancellation latency depends on scheduling and the next suspension point, not a fixed wall-clock guarantee. A retained unawaited task can keep reachable state alive after the caller’s surrounding function returns.
Common Mistakes
- Await the canceled task so cleanup and failure become observable.
- Use a synchronization event instead of guessing task state with a sleep.
Connected lessons
Python asyncio timeout: cancellation and cleanup ownership, Python asyncio TaskGroup: cancel sibling work and retain failure evidence, Python ContextVar: task-local labels without sharing one global binding.
Follow the service contract
Python cancellation review: release a permit before propagating task cancellation.
