.. currentmodule:: asyncio


.. _asyncio-graph:

========================
Call Graph Introspection
========================

**Source code:** :source:`Lib/asyncio/graph.py`

-------------------------------------

asyncio has powerful runtime call graph introspection utilities
to trace the entire call graph of a running *coroutine* or *task*, or
a suspended *future*.  These utilities and the underlying machinery
can be used from within a Python program or by external profilers
and debuggers.

.. versionadded:: next


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

   Print the async call graph for the current task or the provided
   :class:`Task` or :class:`Future`.

   This function prints entries starting from the top frame and going
   down towards the invocation point.

   The function receives an optional *future* argument.
   If not passed, the current running task will be used.

   If the function is called on *the current task*, the optional
   keyword-only *depth* argument can be used to skip the specified
   number of frames from top of the stack.

   If the optional keyword-only *limit* argument is provided, each call stack
   in the resulting graph is truncated to include at most ``abs(limit)``
   entries. If *limit* is positive, the entries left are the closest to
   the invocation point. If *limit* is negative, the topmost entries are
   left. If *limit* is omitted or ``None``, all entries are present.
   If *limit* is ``0``, the call stack is not printed at all, only
   "awaited by" information is printed.

   If *file* is omitted or ``None``, the function will print
   to :data:`sys.stdout`.

   **Example:**

   The following Python code:

   .. code-block:: python

      import asyncio

      async def test():
          asyncio.print_call_graph()

      async def main():
          async with asyncio.TaskGroup() as g:
              g.create_task(test())

      asyncio.run(main())

   will print::

      * Task(name='Task-2', 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()

.. function:: format_call_graph(future=None, /, *, depth=1, limit=None)

   Like :func:`print_call_graph`, but returns a string.
   If *future* is ``None`` and there's no current task,
   the function returns an empty string.


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

   Capture the async call graph for the current task or the provided
   :class:`Task` or :class:`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``.

   If the function is called on *the current task*, the optional
   keyword-only *depth* argument can be used to skip the specified
   number of frames from top of the stack.

   Returns a ``FutureCallGraph`` data class object:

   * ``FutureCallGraph(future, call_stack, awaited_by)``

      Where *future* is a reference to a :class:`Future` or
      a :class:`Task` (or their subclasses.)

      ``call_stack`` is a tuple of ``FrameCallGraphEntry`` objects.

      ``awaited_by`` is a tuple of ``FutureCallGraph`` objects.

   * ``FrameCallGraphEntry(frame)``

      Where *frame* is a frame object of a regular Python function
      in the call stack.


Low level utility functions
===========================

To introspect an async call graph asyncio requires cooperation from
control flow structures, such as :func:`shield` or :class:`TaskGroup`.
Any time an intermediate :class:`Future` object with low-level APIs like
:meth:`Future.add_done_callback() <asyncio.Future.add_done_callback>` is
involved, the following two functions should be used to inform asyncio
about how exactly such intermediate future objects are connected with
the tasks they wrap or control.


.. function:: future_add_to_awaited_by(future, waiter, /)

   Record that *future* is awaited on by *waiter*.

   Both *future* and *waiter* must be instances of
   :class:`Future` or :class:`Task` or their subclasses,
   otherwise the call would have no effect.

   A call to ``future_add_to_awaited_by()`` must be followed by an
   eventual call to the :func:`future_discard_from_awaited_by` function
   with the same arguments.


.. function:: future_discard_from_awaited_by(future, waiter, /)

   Record that *future* is no longer awaited on by *waiter*.

   Both *future* and *waiter* must be instances of
   :class:`Future` or :class:`Task` or their subclasses, otherwise
   the call would have no effect.
