Документация Python неофициальный перевод
Содержание страницы

Интроспекция графа вызововCall Graph Introspection

Исходный код: Lib/asyncio/graph.py


asyncio предоставляет мощные утилиты для интроспекции графа вызовов во время выполнения, чтобы отследить весь граф вызовов работающей корутины или задачи, или приостановленного future. Эти утилиты и лежащая в основе механика могут использоваться как внутри программы на Python, так и внешними профилировщиками и отладчиками.

Добавлено в версии 3.14.

asyncio.print_call_graph(future=None, /, *, file=None, depth=1, limit=None)

Выводит асинхронный граф вызовов для текущей задачи или переданного Task или Future.

Эта функция выводит записи, начиная с верхнего фрейма и двигаясь вниз к точке вызова.

Функция принимает необязательный аргумент future. Если он не передан, будет использоваться текущая выполняемая задача.

Если функция вызывается для текущей задачи, необязательный именованный аргумент depth может использоваться для пропуска указанного количества фреймов с вершины стека.

Если указан необязательный именованный аргумент limit, каждый стек вызовов в результирующем графе обрезается так, чтобы включать не более abs(limit) записей. Если limit положителен, остаются записи, ближайшие к точке вызова. Если limit отрицателен, остаются самые верхние записи. Если limit опущен или равен None, присутствуют все записи. Если limit равен 0, стек вызовов вообще не выводится, выводится только информация «awaited by».

Если file опущен или равен None, функция будет выводить в sys.stdout.

Пример:

Следующий код Python:

import asyncio

async def test():
    asyncio.print_call_graph()

async def main():
    async with asyncio.TaskGroup() as g:
        g.create_task(test(), name='test')

asyncio.run(main())

выведет:

* Task(name='test', id=0x1039f0fe0)
+ Call stack:
|   File 't2.py', line 4, in async test()
+ Awaited by:
   * Task(name='Task-1', id=0x103a5e060)
      + Call stack:
      |   File 'taskgroups.py', line 107, in async TaskGroup.__aexit__()
      |   File 't2.py', line 7, in async main()
asyncio.format_call_graph(future=None, /, *, depth=1, limit=None)

Как print_call_graph(), но возвращает строку. Если future равен None и нет текущей задачи, функция возвращает пустую строку.

asyncio.capture_call_graph(future=None, /, *, depth=1, limit=None)

Захватывает асинхронный граф вызовов для текущей задачи или переданного Task или Future.

Функция принимает необязательный аргумент future. Если он не передан, используется текущая выполняемая задача. Если нет текущей задачи, функция возвращает None.

Если функция вызывается для текущей задачи, необязательный именованный аргумент depth может использоваться для пропуска указанного количества фреймов с вершины стека.

Возвращает объект класса данных FutureCallGraph:

  • FutureCallGraph(future, call_stack, awaited_by)

    Где future – это ссылка на Future или Task (или их подклассы).

    call_stack – это кортеж объектов FrameCallGraphEntry.

    awaited_by – это кортеж объектов FutureCallGraph.

  • FrameCallGraphEntry(frame)

    Где frame – это объект фрейма обычной функции Python в стеке вызовов.

Низкоуровневые вспомогательные функцииLow level utility functions

Для интроспекции асинхронного графа вызовов asyncio требует содействия от структур управления потоком, таких как shield() или TaskGroup. Всякий раз, когда задействован промежуточный объект Future с низкоуровневыми API, такими как Future.add_done_callback(), следует использовать следующие две функции, чтобы сообщить asyncio о том, как именно такие промежуточные future-объекты связаны с задачами, которые они оборачивают или контролируют.

asyncio.future_add_to_awaited_by(future, waiter, /)

Записывает, что future ожидается объектом waiter.

И future, и waiter должны быть экземплярами Future или Task или их подклассов, иначе вызов не будет иметь эффекта.

Вызов future_add_to_awaited_by() должен сопровождаться последующим вызовом функции future_discard_from_awaited_by() с теми же аргументами.

asyncio.future_discard_from_awaited_by(future, waiter, /)

Регистрирует, что future больше не ожидается со стороны waiter.

Оба future и waiter должны быть экземплярами Future или Task или их подклассов, иначе вызов не будет иметь эффекта.