-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
If a task is canceled at the right moment, the cancellation is ignored #74234
Comments
If I run this code: import asyncio as a
@a.coroutine
def coro1():
yield from a.ensure_future(coro2())
print("Still here")
yield from a.sleep(1)
print("Still here 2")
@a.coroutine
def coro2():
yield from a.sleep(1)
res = task.cancel()
print("Canceled task:", res)
loop = a.get_event_loop()
task = a.ensure_future(coro1())
loop.run_until_complete(task) I expect the task to stop shortly after a call to cancel(). It should surely stop when I try to sleep(). But it doesn't. On my machine this prints:
So, cancel() returns True, but the task doesn't seem to be canceled. |
Interesting. It doesn't work for both C and Python versions of the Task. I'll take a look in detail when I return from vacation. |
When task.cancel() called, CancelledError is thrown to coro2. If you add $ cat at.py
import asyncio as a @a.coroutine
def coro1():
yield from a.ensure_future(coro2())
print("Still here")
yield from a.sleep(.1)
print("Still here 2")
@a.coroutine
def coro2():
yield from a.sleep(.1)
res = task.cancel()
print("Canceled task:", res)
yield from a.sleep(.1) # !!! added this line
loop = a.get_event_loop()
task = a.ensure_future(coro1())
loop.run_until_complete(task) $ ./python.exe at.py
Canceled task: True
Traceback (most recent call last):
File "at.py", line 19, in <module>
loop.run_until_complete(task)
File "/Users/inada-n/work/python/cpython/Lib/asyncio/base_events.py", line 465, in run_until_complete
return future.result()
concurrent.futures._base.CancelledError |
This behavior is documented as: https://docs.python.org/3.6/library/asyncio-task.html#asyncio.Task.cancel
I agree that this behavior is somewhat surprising. |
The problem is that the task doesn't catch CancelledError, yet it disappears. |
The problem is CancelledError is not raised, even it's thrown. --- from asyncio import CancelledError
cancelled = False
def coro():
global cancelled
print(1)
yield (1,)
print("cancel")
cancelled = True
#print(2)
#yield (2,) # uncomment this line makes cancel success.
c = coro()
while True:
try:
if cancelled:
r = c.throw(CancelledError)
else:
r = c.send(None)
except StopIteration:
print("end")
break
except CancelledError:
print("cancelled")
break |
In Evgeny's example the 'task' is 'coro1' (not 'coro2'). It has plenty of yield points after being cancelled. |
Since coro1 waiting coro2 when cancelling, Task(coro1).cancel() redirect to Task(coro2).cancel(). But I was wrong about "CancelledError is thrown to coro2." |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: