anyio
anyio copied to clipboard
`CancelScope.cancel` does not trigger cancellation if called before we enter the cancel scope
The following code example shows the issue:
import anyio
async def main():
cancel_scope = anyio.CancelScope()
cancel_scope.cancel() # We call `cancel` before `__enter__`
with cancel_scope:
await anyio.sleep(1) # Checkpoint to allow anyio to check for cancellation
cancel_scope.cancel() # Try `cancel` again just for good measure
await anyio.sleep(1) # Checkpoint to allow anyio to check for cancellation
print("foo") # We get this far even though we cancelled the cancel scope long before.
anyio.run(main)
This code prints foo
. I expect it to print nothing because we cancelled the cancel scope long before the call to print
.
If I remove the call to CancelScope.cancel
before the call to CancelScope.__enter__
then the code works as expected (prints nothing).
Never have I imagined a situation where somebody tries to do something with a cancel scope before entering it.
It is an edge case, indeed. :) Alternatively, let
cancel_scope.cancel() # We call `cancel` before `__enter__`
raise a RuntimeError("Cancel called before __enter__")
. This way, the user knows up front that this is not supported.
I decided to implement this on asyncio because it also works on Trio this way.