Сообщить об ошибке.

Асинхронный менеджер TaskGroup() модуля asyncio в Python

Синтаксис:

import asyncio

# Новое в Python 3.11.
async with asyncio.TaskGroup() as tg:
    task1 = tg.create_task(some_coro(...))
    ...

Возвращаемое значение:

  • группа задач TaskGroup.

Описание:

Класс TaskGroup() (добавлен в Python 3.11.) модуля asyncio представляет собой асинхронный менеджер контекста, содержащий группу задач.

Группы задач asyncio.TaskGroup() сочетают в себе API создания задач с удобным и надежным способом ожидания завершения всех задач в группе.

Отдельные задачи можно добавлять в группу с помощью метода TaskGroup.create_task(). Все задачи ожидаются при выходе из менеджера контекста.

TaskGroup.create_task(coro, *, name=None, context=None):

Метод TaskGroup.create_task() создает задачу в этой группе задач. Принимаемые аргументы и поведение этого метода совпадает с описанием asyncio.create_task().

Пример:

async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(some_coro(...))
        task2 = tg.create_task(another_coro(...))
    print("Обе задачи уже выполнены.")

Оператор async with будет ожидать завершения всех задач в группе. Во время ожидания, в группу, все еще могут быть добавлены новые задачи (например, путем передачи экземпляра tg в одну из сопрограмм и вызова tg.create_task() в этой сопрограмме). После завершения последней задачи и выхода из блока async with в группу нельзя добавлять новые задачи.

При первом сбое любой из задач, принадлежащих группе tg, с исключением asyncio.CancelledError, оставшиеся задачи в группе отменяются. После этого в группу нельзя будет добавить больше задач. В этот момент, если тело асинхронного оператора with все еще активно (т. е. __aexit__() еще не вызывалась), то задача, непосредственно содержащая асинхронный оператор with, также отменяется. Полученный asyncio.CancelledError прервет ожидание, но не выйдет из содержащего оператора async with.

После завершения всех задач, если какие-либо задачи завершились сбоем с исключением, отличным от asyncio.CancelledError, эти исключения объединяются в ExceptionGroup или BaseExceptionGroup (соответственно; смотрите их документацию), которая затем вызывается.

Два базовых исключения обрабатываются особым образом: если какая-либо задача завершается с ошибкой с помощью KeyboardInterrupt или SystemExit, то группа задач по-прежнему отменяет оставшиеся задачи и ожидает их, но затем повторно вызывается первоначальная KeyboardInterrupt или SystemExit вместо ExceptionGroup или BaseExceptionGroup.

Если тело оператора async with завершается с исключением (поэтому __aexit__() вызывается с набором исключений), то ситуация обрабатывается так же, как если бы одна из задач не удалась: оставшиеся задачи отменяются, а затем ожидаются (т.е. исключения отмены НЕ группируются в группу исключений и вызываются). Исключение, переданное в __aexit__(), если оно не является asyncio.CancelledError, также включается в группу исключений. Для KeyboardInterrupt и SystemExit делается тот же особый случай, что и в предыдущем абзаце.