呼び出しグラフのイントロスペクション

ソースコード: Lib/asyncio/graph.py


asyncio は、実行中の コルーチン や タスク、または中断中の Future の呼び出しグラフ全体を実行時にたどる、強力なイントロスペクション機能を備えています。 これらの機能とその基盤の仕組みは、Python プログラム内からも、外部のプロファイラーやデバッガーからも利用できます。

参考

コマンドラインのイントロスペクションツール

実行中の別の Python プロセス内のタスクを調べるコマンドラインツールです。

Added in version 3.14.

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

現在のタスク、または指定した Task や Future の非同期呼び出しグラフを表示します。

スタックの最上部のフレームから、呼び出し元の起点に向かって順に表示します。

省略可能な future 引数を受け取ります。 指定しなければ、現在実行中のタスクを使います。

現在のタスク に対して呼び出す場合、省略可能なキーワード専用引数 depth で、スタックの最上部から飛ばすフレーム数を指定できます。

省略可能なキーワード専用引数 limit を指定すると、グラフ内の各コールスタックのエントリー数を最大 abs(limit) 個に制限します。 limit が正なら呼び出し元の起点に近いエントリーを、負ならスタックの最上部に近いエントリーを残します。 limit を省略するか None にすると、すべてのエントリーを含めます。 0 の場合、コールスタックは表示せず、何に await されているかの情報だけを表示します。

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)

Like print_call_graph(), but returns a string. If future is None and there's no current task, the function returns an empty string.

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

現在のタスク、または指定した Task や Future の非同期呼び出しグラフを取得します。

The function receives an optional future argument. If not passed, the current running task will be used. If there's no current task, the function returns None.

現在のタスク に対して呼び出す場合、省略可能なキーワード専用引数 depth で、スタックの最上部から飛ばすフレーム数を指定できます。

FutureCallGraph データクラスのオブジェクトを返します。

  • FutureCallGraph(future, call_stack, awaited_by)

    future は Future または Task (またはそのサブクラス) への参照です。

    call_stack は FrameCallGraphEntry オブジェクトのタプルです。

    awaited_by は FutureCallGraph オブジェクトのタプルです。

  • FrameCallGraphEntry(frame)

    frame は、コールスタック内の通常の Python 関数のフレームオブジェクトです。

低水準の補助関数

非同期呼び出しグラフを調べるために、asyncio は shield() や TaskGroup などの制御フローを扱う仕組みとの連携を必要とします。 Future.add_done_callback() のような低水準 API を使う中間的な Future オブジェクトが関わる場合は、次の二つの関数を使ってください。 これにより、その Future が、ラップしたり制御したりするタスクとどうつながっているかを asyncio に伝えます。

asyncio.future_add_to_awaited_by(future, waiter, /)

future が waiter に await されていることを記録します。

future と waiter はどちらも Future または Task、あるいはそのサブクラスのインスタンスでなければなりません。 それ以外の場合、呼び出しても何も起こりません。

future_add_to_awaited_by() を呼び出した後は、いずれ同じ引数で future_discard_from_awaited_by() を呼び出す必要があります。

asyncio.future_discard_from_awaited_by(future, waiter, /)

future が waiter に await されなくなったことを記録します。

future と waiter はどちらも Future または Task、あるいはそのサブクラスのインスタンスでなければなりません。 それ以外の場合、呼び出しても何も起こりません。