oct
Loading...
Searching...
No Matches
oct.docs.call_trace Namespace Reference

Classes

class  TraceUnavailable
class  RuntimeTrace
class  TraceComparison

Functions

Path default_package_root ()
str _fold (str qualname)
RuntimeTrace trace_oct_command (list[str] args, Path|None package_root=None)
bool _is_set_aside (str name)
bool _calls_dbg (ast.AST node)
TraceComparison compare (RuntimeTrace trace, StaticCallGraph static, str root, int|None max_depth=None)
str to_diff_dot (TraceComparison cmp, str title)

Variables

dict _SET_ASIDE
tuple _TOOL_IDS = (2, 3, 4)
str _TOOL_NAME = "oct-docs-callgraph-trace"
str ENTRY = "<entry>"

Detailed Description

Purpose
-------
The runtime half of chart C of the overview-charts plan
(docs/DOCS_OVERVIEW_CHARTS_PLAN_2026-09-27.md in the workspace): run one
``oct`` command in this process, record every call between oct functions
while it runs, and compare what ran with the static call graph that
:mod:`oct.deps.call_graph` resolves from the source.

The static graph says what a command CAN call; the trace says what one run
DID call. The comparison is the point: an edge only the trace has is a call
the static resolver cannot see (a dispatch table, Click's command dispatch,
a decorator's wrapper), and a function only the static graph has is a path
that run did not take. The first trace of ``oct git commit`` (2026-09-27)
found one resolver gap this way (dispatch tables, since fixed).

Calls are captured with :mod:`sys.monitoring` (``PY_START``): for each call
into oct code the capture walks back from the new frame to the nearest
oct frame, which is the caller, and notes which library, if any, sat in
between (Click, contextlib). Code outside the oct package is disabled after
its first event, so the overhead is small. ``_dbg`` records say which
functions ran but never who called them, so they cannot supply the edges;
the ``_dbg`` stream of a traced run is available separately through
oc_diagnostics' own config (``"*": 9`` and ``log_format: "jsonl"``).

Responsibilities
----------------
- :func:`trace_oct_command` - run ``oct ARGS`` in-process under
  ``sys.monitoring`` and return a :class:`RuntimeTrace`.
- :func:`compare` - set a trace against a :class:`StaticCallGraph` below one
  root function, and around it; name the functions that ran with no
  ``_dbg`` call.
- :func:`to_diff_dot` - render the comparison: both, trace only, static only.

Diagnostics
-----------
Domain: OCT-DOCS
Levels:
    L2 - trace entry / exit with sizes
    L3 - comparison totals, tool-id selection
    L4 - deep tracing

Contracts
---------
- The traced command runs FOR REAL, in the current directory, exactly as
  ``oct ARGS`` would: ``git commit`` makes a commit. Callers must say so.
- The ``sys.monitoring`` tool is always released, whatever the traced
  command does (``finally``), so a second trace in the same process works.
- Frames above the trace's own entry are never attributed: the outer
  ``oct docs`` invocation does not appear in the graph.
- Module bodies run by imports during the command, and Python 3.14's lazy
  annotation functions, are set aside and counted, as the static graph sets
  module-level code aside.

Dependencies
------------
- oct.core.diagnostics (_dbg structured logger)
- oct.deps.call_graph (StaticCallGraph - the graph a trace is set against)
- oct.docs.callgraph (reachable - the shared closure)
- oct (lazy; locates the imported oct package, the default package root)
- oct.cli (lazy; cli - the command group the trace runs)
- click (lazy; ClickException and Abort raised by the traced command)

Function Documentation

◆ _calls_dbg()

bool oct.docs.call_trace._calls_dbg ( ast.AST node)
protected

Definition at line 258 of file call_trace.py.

Here is the caller graph for this function:

◆ _fold()

str oct.docs.call_trace._fold ( str qualname)
protected

Definition at line 123 of file call_trace.py.

◆ _is_set_aside()

bool oct.docs.call_trace._is_set_aside ( str name)
protected

Definition at line 235 of file call_trace.py.

Here is the caller graph for this function:

◆ compare()

TraceComparison oct.docs.call_trace.compare ( RuntimeTrace trace,
StaticCallGraph static,
str root,
int | None max_depth = None )
Set *trace* against *static* below *root* (a qualified name) and around it.

Definition at line 267 of file call_trace.py.

Here is the call graph for this function:

◆ default_package_root()

Path oct.docs.call_trace.default_package_root ( )
The directory holding the imported ``oct`` package (the oct subproject).

Definition at line 117 of file call_trace.py.

Here is the caller graph for this function:

◆ to_diff_dot()

str oct.docs.call_trace.to_diff_dot ( TraceComparison cmp,
str title )
Render *cmp*: solid blue ran (and is static), green trace only, dashed static only.

Definition at line 319 of file call_trace.py.

◆ trace_oct_command()

RuntimeTrace oct.docs.call_trace.trace_oct_command ( list[str] args,
Path | None package_root = None )
Run ``oct ARGS`` in this process, recording every oct-to-oct call.

Returns the trace even when the command fails; its exit code and any
exception are recorded on it. Raises :class:`TraceUnavailable` when
``sys.monitoring`` cannot be used.

Definition at line 129 of file call_trace.py.

Here is the call graph for this function:

Variable Documentation

◆ _SET_ASIDE

dict oct.docs.call_trace._SET_ASIDE
protected
Initial value:
1= {
2 ".<module>": "module body run by an import",
3 ".__annotate__": "annotation function (Python 3.14 lazy annotations)",
4}

Definition at line 85 of file call_trace.py.

◆ _TOOL_IDS

tuple oct.docs.call_trace._TOOL_IDS = (2, 3, 4)
protected

Definition at line 91 of file call_trace.py.

◆ _TOOL_NAME

str oct.docs.call_trace._TOOL_NAME = "oct-docs-callgraph-trace"
protected

Definition at line 92 of file call_trace.py.

◆ ENTRY

str oct.docs.call_trace.ENTRY = "<entry>"

Definition at line 95 of file call_trace.py.