|
oct
|
Classes | |
| class | SectionItem |
Functions | |
| list[SectionItem]|None | dependency_items (str|None docstring) |
| str|None | entry_marker (str purpose) |
| list[tuple[str, bool]] | dependency_entries (str|None docstring) |
| str|None | _extract_module_docstring (str source) |
| list[str] | extract_dependencies (str source, *, bool eager_only=False) |
| bool | _should_skip (Path path, Path root) |
| str | module_name_for (Path py_file, Path root) |
| tuple[dict[str, list[str]], dict[str, list[str]]] | build_dependency_graphs (Path root) |
| dict[str, list[str]] | build_dependency_graph (Path root, *, bool eager_only=False) |
| list[list[str]] | detect_cycles (dict[str, list[str]] graph) |
| str | to_json (dict[str, list[str]] graph, list[list[str]] cycles) |
| str | to_mermaid (dict[str, list[str]] graph) |
| str | to_dot (dict[str, list[str]] graph) |
| int | audit_pins (Path root, bool json_output=False) |
| dict | _parse_toml_deps_fallback (Path toml_path) |
| int | run_deps (Path root, list[str]|None argv=None) |
Variables | |
| _DEP_SECTION_RE | |
| _BULLET_RE = re.compile(r'^[ \t]*[-*][ \t]+(.*)$') | |
| _DEP_NAME_RE = re.compile(r'^`?(\S+?)`?[ \t]*(?:[-—:(].*)?$') | |
| _MARKER_RE = re.compile(r'^(lazy|not imported)(?![\w-])') | |
Purpose
-------
Analyse inter-module dependencies within an Option C project by parsing
the ``Dependencies`` docstring section from all Python files.
Responsibilities
----------------
- Walk the project tree and extract ``Dependencies`` sections from module
docstrings. The section parsing (:func:`dependency_items`,
:func:`entry_marker`) is shared with the ``dependencies_match`` lint
rule in :mod:`oct.deps.dependency_check`, so both read an entry alike.
- Build a directed dependency graph (adjacency list).
- Detect circular dependencies via depth-first search, over the EAGER
entries only: an entry whose purpose starts with ``lazy`` or ``not
imported`` (operator ruling 2026-09-28) is drawn but never part of a
cycle, because lazy imports are how the code breaks import cycles.
- Output the graph in multiple formats: terminal summary, JSON, Mermaid,
and DOT.
Diagnostics
-----------
Domain: OCT-DEPS
Levels:
L2 - lifecycle
L3 - semantic details
L4 - deep tracing
Contracts
---------
- Must not import project modules; analysis is purely static.
- Must exit 1 if circular dependencies are detected.
- Must handle missing or malformed Dependencies sections gracefully.
Dependencies
------------
- oct.core.exclusions (directory exclusion lists)
- oct.core.diagnostics (_dbg structured logger)
- tomli (lazy; TOML parsing for audit_pins on Python before 3.11)
|
protected |
Extract the module-level docstring from Python source.
Definition at line 139 of file oct_deps.py.
|
protected |
Minimal fallback TOML parser - extracts dependency lines only.
Definition at line 411 of file oct_deps.py.
|
protected |
Check if a path should be excluded. The exclusion lists name DIRECTORIES, and are matched against the directory components only, as the linter's ``is_excluded_dir`` does. Until 2026-09-27 the file name was matched too, so the ``cache``, ``logs`` and ``venv`` wildcards silently dropped any module whose name merely started with one of them: ``oct.testing.cache``, ``oc_chat.core.cache_usage`` and three others were missing from ``oct deps``, every dependency overview page and every call graph.
Definition at line 165 of file oct_deps.py.
| int oct.deps.oct_deps.audit_pins | ( | Path | root, |
| bool | json_output = False ) |
Audit pyproject.toml dependencies for unpinned version specifiers.
Reads ``[project.dependencies]`` and
``[project.optional-dependencies]`` from ``pyproject.toml``. Reports
dependencies that use open ranges (``>=``, ``>``) with no exact or
upper-bound constraint alongside those that are strictly pinned.
Parameters
----------
root
Project root containing ``pyproject.toml``.
json_output
If ``True``, prints a JSON summary. Otherwise prints a human-
readable table.
Returns
-------
Exit code: ``0`` if all dependencies have upper-bound or exact pins,
``1`` if any open-ended ``>=``-only or ``>``-only specs are found,
``2`` if ``pyproject.toml`` could not be read.
Definition at line 307 of file oct_deps.py.
| dict[str, list[str]] oct.deps.oct_deps.build_dependency_graph | ( | Path | root, |
| * | , | ||
| bool | eager_only = False ) |
One graph of :func:`build_dependency_graphs`: every entry, or the eager ones.
Definition at line 236 of file oct_deps.py.
| tuple[dict[str, list[str]], dict[str, list[str]]] oct.deps.oct_deps.build_dependency_graphs | ( | Path | root | ) |
Walk the project once; return ``(every entry, eager entries only)`` graphs. Keys are dotted import paths (OI-521), so modules sharing a stem across packages no longer overwrite one another.
Definition at line 208 of file oct_deps.py.
| list[tuple[str, bool]] oct.deps.oct_deps.dependency_entries | ( | str | None | docstring | ) |
``(name, eager)`` for every bulleted entry of *docstring*'s Dependencies section. The name comes from the entry's first line; the marker from the joined text, so ``oct deps`` and the ``dependencies_match`` rule read a wrapped entry the same way. An entry marked ``lazy`` or ``not imported`` is not eager.
Definition at line 119 of file oct_deps.py.
| list[SectionItem] | None oct.deps.oct_deps.dependency_items | ( | str | None | docstring | ) |
The items of *docstring*'s Dependencies section, or ``None`` if it has none. A non-bullet line after a bullet continues it; a non-bullet line before any bullet is an item of its own (``bulleted`` false).
Definition at line 92 of file oct_deps.py.
| list[list[str]] oct.deps.oct_deps.detect_cycles | ( | dict[str, list[str]] | graph | ) |
Detect circular dependencies using DFS. Returns list of cycle paths.
Definition at line 244 of file oct_deps.py.
| str | None oct.deps.oct_deps.entry_marker | ( | str | purpose | ) |
``"lazy"``, ``"not imported"`` or ``None`` for an entry's purpose text.
Definition at line 113 of file oct_deps.py.
| list[str] oct.deps.oct_deps.extract_dependencies | ( | str | source, |
| * | , | ||
| bool | eager_only = False ) |
Parse the Dependencies section from a module docstring. Returns a list of dependency module names. With *eager_only*, entries marked ``lazy`` or ``not imported`` are left out (cycle detection).
Definition at line 153 of file oct_deps.py.
| str oct.deps.oct_deps.module_name_for | ( | Path | py_file, |
| Path | root ) |
Compute a dotted import-path key for *py_file* relative to *root*. OI-521: using ``py_file.stem`` collided whenever two packages contain modules of the same name (e.g. ``a/util.py`` and ``b/util.py`` both reduced to ``util``). Returning the dotted import path makes each key unique and aligns with the dotted names typically used in ``Dependencies`` docstring sections. ``__init__.py`` resolves to its parent package's dotted name; a file directly under *root* keeps its stem as the fallback.
Definition at line 186 of file oct_deps.py.
| int oct.deps.oct_deps.run_deps | ( | Path | root, |
| list[str] | None | argv = None ) |
Run dependency analysis on the given project root. Returns exit code: 0 if no cycles, 1 if circular dependencies found.
Definition at line 432 of file oct_deps.py.
| str oct.deps.oct_deps.to_dot | ( | dict[str, list[str]] | graph | ) |
Format dependency graph as DOT (Graphviz) syntax.
Definition at line 294 of file oct_deps.py.
| str oct.deps.oct_deps.to_json | ( | dict[str, list[str]] | graph, |
| list[list[str]] | cycles ) |
Format dependency graph as JSON.
Definition at line 276 of file oct_deps.py.
| str oct.deps.oct_deps.to_mermaid | ( | dict[str, list[str]] | graph | ) |
Format dependency graph as Mermaid diagram syntax.
Definition at line 285 of file oct_deps.py.
|
protected |
Definition at line 63 of file oct_deps.py.
|
protected |
Definition at line 71 of file oct_deps.py.
|
protected |
Definition at line 59 of file oct_deps.py.
|
protected |
Definition at line 75 of file oct_deps.py.