summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2024-09-11 15:43:24 (GMT)
committerGitHub <noreply@github.com>2024-09-11 15:43:24 (GMT)
commitef05801ba0cbf090034df17e2a0420fb42c2d538 (patch)
treecfa9b33ac8631f7179376b4b2070403c9e3874b4
parent5436d8b9c397c48d9b0d5f9d4ad5e1d5a5d500f6 (diff)
downloadcpython-ef05801ba0cbf090034df17e2a0420fb42c2d538.zip
cpython-ef05801ba0cbf090034df17e2a0420fb42c2d538.tar.gz
cpython-ef05801ba0cbf090034df17e2a0420fb42c2d538.tar.bz2
gh-108951: Document how to terminate an asyncio.TaskGroup (#123837)
We don't want to add another API, since the recipe is straightforward and rarely needed. The advantage is that we could backport this to the earliest Python version that has taskgroups (3.11, alas in security mode already, so we'll just do 3.12 and 3.13).
-rw-r--r--Doc/library/asyncio-task.rst47
1 files changed, 47 insertions, 0 deletions
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index abf1726..4716a3f 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -414,6 +414,53 @@ reported by :meth:`asyncio.Task.cancelling`.
Improved handling of simultaneous internal and external cancellations
and correct preservation of cancellation counts.
+Terminating a Task Group
+------------------------
+
+While terminating a task group is not natively supported by the standard
+library, termination can be achieved by adding an exception-raising task
+to the task group and ignoring the raised exception:
+
+.. code-block:: python
+
+ import asyncio
+ from asyncio import TaskGroup
+
+ class TerminateTaskGroup(Exception):
+ """Exception raised to terminate a task group."""
+
+ async def force_terminate_task_group():
+ """Used to force termination of a task group."""
+ raise TerminateTaskGroup()
+
+ async def job(task_id, sleep_time):
+ print(f'Task {task_id}: start')
+ await asyncio.sleep(sleep_time)
+ print(f'Task {task_id}: done')
+
+ async def main():
+ try:
+ async with TaskGroup() as group:
+ # spawn some tasks
+ group.create_task(job(1, 0.5))
+ group.create_task(job(2, 1.5))
+ # sleep for 1 second
+ await asyncio.sleep(1)
+ # add an exception-raising task to force the group to terminate
+ group.create_task(force_terminate_task_group())
+ except* TerminateTaskGroup:
+ pass
+
+ asyncio.run(main())
+
+Expected output:
+
+.. code-block:: text
+
+ Task 1: start
+ Task 2: start
+ Task 1: done
+
Sleeping
========