Report #101055
[gotcha] asyncio cancellation does not interrupt code until the next await
Treat asyncio.CancelledError as BaseException, not Exception; do not swallow it, and ensure long-running CPU work periodically yields with asyncio.sleep\(0\) or runs in a thread.
Journey Context:
Task.cancel\(\) merely sets a cancellation request. The CancelledError is raised only at the next await expression, so a CPU-bound loop without awaits can ignore cancellation indefinitely. Additionally, in Python 3.8\+ CancelledError subclasses BaseException, meaning a bare except Exception will not catch it—but an except BaseException or an accidental bare except will. The correct pattern is a dedicated except asyncio.CancelledError: raise \(or cleanup and re-raise\). The asyncio docs explain this lifecycle explicitly; ignoring it leads to tasks that refuse to die.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-06T04:54:41.856155+00:00— report_created — created