Skip to content

Doc impact

doc_impact

Doc impact analysis — doc refs, undocumented symbols, stale signatures.

DocImpactResult

Bases: TypedDict

Output shape of :func:analyze_doc_impact.

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
class DocImpactResult(TypedDict):
    """Output shape of :func:`analyze_doc_impact`."""

    doc_refs: dict[str, list[DocRefEntry]]
    undocumented: list[str]
    stale_signatures: list[StaleSignature]

DocRefEntry

Bases: TypedDict

Single documentation reference (backtick mention or heading hit).

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
class DocRefEntry(TypedDict):
    """Single documentation reference (backtick mention or heading hit)."""

    file: str
    line: int

StaleSignature

Bases: TypedDict

Stale signature record extracted from a doc code block.

actual_sig is added only after matching against the AST signatures; intermediate entries produced by :func:_match_signature_line omit it.

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
class StaleSignature(TypedDict):
    """Stale signature record extracted from a doc code block.

    ``actual_sig`` is added only after matching against the AST signatures;
    intermediate entries produced by :func:`_match_signature_line` omit it.
    """

    symbol: str
    file: str
    doc_sig: str
    line: int
    actual_sig: NotRequired[str]

analyze_doc_impact(root, symbols)

Full doc impact analysis for a set of symbols.

Combines doc refs, undocumented detection, and stale signature detection.

Parameters:

Name Type Description Default
root Path

Project root directory.

required
symbols list[str]

Symbol names to analyze.

required

Returns:

Type Description
DocImpactResult

Dict with doc_refs, undocumented, stale_signatures.

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
def analyze_doc_impact(
    root: Path,
    symbols: list[str],
) -> DocImpactResult:
    """Full doc impact analysis for a set of symbols.

    Combines doc refs, undocumented detection, and stale
    signature detection.

    Args:
        root: Project root directory.
        symbols: Symbol names to analyze.

    Returns:
        Dict with ``doc_refs``, ``undocumented``, ``stale_signatures``.
    """
    refs = find_doc_refs(root, symbols)
    return {
        "doc_refs": refs,
        "undocumented": find_undocumented(refs),
        "stale_signatures": find_stale_signatures(root, symbols),
    }

find_doc_refs(root, symbols)

Find documentation references for given symbols.

Parameters:

Name Type Description Default
root Path

Project root directory.

required
symbols list[str]

Symbol names to search for in docs.

required

Returns:

Type Description
dict[str, list[DocRefEntry]]

Dict mapping symbol name to list of references

dict[str, list[DocRefEntry]]

(each with file and line keys).

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
def find_doc_refs(
    root: Path,
    symbols: list[str],
) -> dict[str, list[DocRefEntry]]:
    """Find documentation references for given symbols.

    Args:
        root: Project root directory.
        symbols: Symbol names to search for in docs.

    Returns:
        Dict mapping symbol name to list of references
        (each with ``file`` and ``line`` keys).
    """
    doc_files = _collect_doc_files(root)
    refs: dict[str, list[DocRefEntry]] = {s: [] for s in symbols}
    for sym in symbols:
        for doc_file in doc_files:
            hits = _search_symbol_in_file(doc_file, sym, root)
            refs[sym].extend(hits)
    return refs

find_stale_signatures(root, symbols=None)

Detect stale code signatures in documentation.

Compares def / class signatures in doc code blocks against actual AST signatures.

Parameters:

Name Type Description Default
root Path

Project root directory.

required
symbols list[str] | None

Symbol names to check. If None, check all symbols.

None

Returns:

Type Description
list[StaleSignature]

List of dicts with symbol, file, doc_sig,

list[StaleSignature]

actual_sig, and line keys.

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
def find_stale_signatures(
    root: Path,
    symbols: list[str] | None = None,
) -> list[StaleSignature]:
    """Detect stale code signatures in documentation.

    Compares ``def`` / ``class`` signatures in doc code blocks
    against actual AST signatures.

    Args:
        root: Project root directory.
        symbols: Symbol names to check. If ``None``, check all symbols.

    Returns:
        List of dicts with ``symbol``, ``file``, ``doc_sig``,
        ``actual_sig``, and ``line`` keys.
    """
    ast_sigs = _extract_ast_signatures(root)
    doc_files = _collect_doc_files(root)
    if symbols is None:
        sym_set = {qk.rsplit(".", 1)[-1] for qk in ast_sigs}
    else:
        sym_set = set(symbols)
    # Build reverse index: bare name → list of (qualified_key, sig)
    bare_index: dict[str, list[str]] = {}
    for qkey in ast_sigs:
        bare = qkey.rsplit(".", 1)[-1]
        bare_index.setdefault(bare, []).append(qkey)
    stale: list[StaleSignature] = []
    for doc_file in doc_files:
        doc_sigs = _extract_doc_signatures(doc_file, sym_set, root)
        for entry in doc_sigs:
            sym_name = entry["symbol"]
            qkeys = bare_index.get(sym_name, [])
            if not qkeys:
                continue
            doc_sig = entry["doc_sig"].strip()
            # Conservative: report stale only if NO qualified match agrees
            if all(ast_sigs[qk].strip() != doc_sig for qk in qkeys):
                entry["actual_sig"] = ast_sigs[qkeys[0]]
                stale.append(entry)
    return stale

find_undocumented(doc_refs)

Return symbols that have no documentation references.

Parameters:

Name Type Description Default
doc_refs dict[str, list[DocRefEntry]]

Output of find_doc_refs.

required

Returns:

Type Description
list[str]

List of symbol names with empty references.

Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
Python
def find_undocumented(
    doc_refs: dict[str, list[DocRefEntry]],
) -> list[str]:
    """Return symbols that have no documentation references.

    Args:
        doc_refs: Output of ``find_doc_refs``.

    Returns:
        List of symbol names with empty references.
    """
    return [sym for sym, refs in doc_refs.items() if not refs]