Skip to content

gh-98641: Don't portray asyncio.TaskGroup as a replacement for asyncio.gather in docs #98659

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

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions Doc/library/asyncio-task.rst
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,9 @@ Creating Tasks

.. note::

:meth:`asyncio.TaskGroup.create_task` is a newer alternative
that allows for convenient waiting for a group of related tasks.
:meth:`asyncio.TaskGroup.create_task` is a new alternative
based on `structural concurrency principles <https://en.wikipedia.org/wiki/Structured_concurrency>`_
that allows for waiting for a group of related tasks with strong safety guarantees.

.. important::

Expand Down Expand Up @@ -328,7 +329,7 @@ Example::
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(some_coro(...))
task2 = tg.create_task(another_coro(...))
print("Both tasks have completed now.")
print(f"Both tasks have completed now: {task1.result()}, {task2.result()}")

The ``async with`` statement will wait for all tasks in the group to finish.
While waiting, new tasks may still be added to the group
Expand Down Expand Up @@ -447,8 +448,15 @@ Running Tasks Concurrently
Tasks/Futures to be cancelled.

.. note::
A more modern way to create and run tasks concurrently and
wait for their completion is :class:`asyncio.TaskGroup`.
A new alternative to create and run tasks concurrently and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there should be this much information in a note.

Copy link
Contributor Author

@why-not-try-calmer why-not-try-calmer Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your comment. It's difficult to turn into something actionable. Can you clarify what you'd remove, bearing in mind the purpose and arguments put forth in this PR?

Copy link
Contributor

@kumaraditya303 kumaraditya303 Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly this belongs more to a FAQ entry than reference docs. But this note was already there, I suggest to only explain the case why gather should be used and keep it short something like "Use asyncio.gather if you want to concurrently run coroutines and cancellation of one does not affects others otherwise it is recommend to use TaskGroups". Feel free to word it better!

wait for their completion is :class:`asyncio.TaskGroup`. *TaskGroup*
provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks.
That is, if a task (or a subtask, a task scheduled by a task)
raises an exception, *TaskGroup* will, while *gather* will not,
cancel the remaining scheduled tasks). However the terser *gather* might be
preferred for *Iterable* of tasks which individually handle their own exceptions, or more
generally, when having some tasks survive the cancellation
of others is an acceptable outcome.

.. _asyncio_example_gather:

Expand Down