Guido van Rossum <[email protected]> added the comment:
Oh, wait. The new Task.cancelling() API helps tell the difference between the
*parent* task being cancelled "from outside" vs. the task group itself
cancelling the parent task so as to break out of an await like the following:
async with TaskGroup() as g:
g.create_task(...)
await <something>
when the await is cancelled, __aexit__() is called with a CancelledError, and
we need to tell whether it was cancelled from the outside or by the completion
callback on one of the tasks managed by the task group.
The EdgeDB TaskGroup monkey-patched the parent task's cancel() method, and the
new asyncio.TaskGroup instead checks parent.cancelled().
However, AFAICT when *any* of the task managed by the TaskGroup exits with
CancelledError, this is *ignored* (in both the EdgeDB version and in
asyncio.TaskGroup). The assumption here seems to be that the only reason a
managed task raises CancelledError is because it was cancelled by the TaskGroup.
A fix for that would be to separately keep track (maybe in a separate weak
dict, or some other data structure -- maybe a flag on the task itself?) of
which tasks are successfully cancelled by the TaskGroup. We can then treat a
CancelledError bubbling out of a managed task that we *didn't* cancel as any
other exception, causing it to abort the task group (i.e., cancel all other
tasks).
Is that what you are looking for? (But I think this could be solved even in 3.9
without resorting to cancel messages.)
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue46771>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com