Skip to main content

pyoverview

Static analyzer that turns a Python project into a single, deterministic Markdown overview: metadata, directory tree, entry points, per-file docstrings/imports/exports/signatures, a project-wide symbol table, resolved "used by" back-references (with confidence levels), a module dependency graph, a flattened public API index, and an unresolved-reference report.

Built entirely on the ast module. It never imports or executes the project it analyzes.

Installation

Distributed on PyPI as cpm-pyoverview (the pyoverview name was already taken by an unrelated package); the installed command is cpm-pyoverview.

uv tool install cpm-pyoverview
# or
pipx install cpm-pyoverview
# or
pip install cpm-pyoverview

For local development instead of installing from PyPI, see CONTRIBUTING.md.

Usage

cpm-pyoverview ./path/to/project --output overview.md

Options:

--output PATH                 Write to PATH instead of stdout
--include PATTERN             Glob pattern to include (repeatable)
--exclude PATTERN             Glob pattern to exclude (repeatable)
--python-version VERSION      Declared target version (metadata only, see limitations)
--include-private             Include underscore-prefixed definitions in the Files section
--include-tests               Include tests/ files in the rendered Files section
--show-line-numbers            Append :line to reference locations
--include-local-references     Include "used by" references originating from the same file
--strict                      Exit non-zero if any file has a syntax error
--fail-on-unresolved           Exit non-zero if any reference is unresolved
--version                     Print the installed version and exit

Architecture

Three passes, each backed by a focused module:

  1. Parse (parser.py, syntax-only, per file, via ast_visitors.py) → ParsedModule (internal only -- holds the retained AST tree).
  2. Resolve (project_resolver.py orchestrating module_resolver.py, import_resolver.py, export_resolver.py, binding.py, symbol_table.py, entry_point_resolver.py) → ResolvedModule + project-wide symbol table + dependency edges.
  3. Reference (reference_resolver.py, bounded type inference) → graded resolved / probable / unresolved usage references.

markdown_renderer.py is a pure function (ProjectInfo -> str); cli.py wires the pipeline together.

Known limitations

  • Method-call type inference is bounded, not full type checking: single-function scope, one hop of attribute/alias propagation, and a binding is invalidated (never guessed) the moment it sees two different constructor assignments. No interprocedural or control-flow-sensitive analysis beyond that.
  • Export inference is conservative: imported names are never treated as re-exports unless they also appear in a statically resolved __all__ -- even in __init__.py. This avoids silently promoting ordinary imports to public API, at the cost of missing some intentional re-export patterns.
  • --python-version is metadata-plus-parsing only: stdlib-module classification always uses the running interpreter's sys.stdlib_module_names, since Python does not ship a way to query an arbitrary historical version's stdlib module list.
  • Entry-point detection is conservative: only if __name__ == "__main__": guards and pyproject.toml [project.scripts] / [project.gui-scripts]. Framework-specific route/command discovery (Flask, Click, FastAPI, etc.) is not attempted.
  • Module-name resolution is heuristic: a top-level src/ directory, if present, is treated as the import root; otherwise the project root is. This covers conventional layouts but is not a full sys.path/package configuration resolution.
  • Dynamic Python is always unresolved, never guessed at: getattr/setattr, importlib.import_module/__import__, wildcard imports, monkeypatching, and framework-based discovery all surface in the "Unresolved References" section with a reason, rather than being silently omitted or confidently mis-resolved.
  • Name-binding lookup is module-flat, not precisely scope-nested: a name shadowed only inside one function can occasionally over-resolve against an unrelated module-level binding of the same name.

Testing

uv run pytest

Includes unit tests per component and an integration test running the full pipeline against tests/fixtures/demo_project (multi-package, re-exports, tests, a circular dependency, aliased imports, async methods, a dynamic import, and an ambiguous method call), snapshot-compared against tests/integration/__snapshots__/demo_project.md. Regenerate the snapshot deliberately after a reviewed output-format change with:

UPDATE_SNAPSHOTS=1 uv run pytest tests/integration

Metadata

Release files for cpm-pyoverview 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cpm-pyoverview 0.1.0
File Size Uploaded
cpm_pyoverview-0.1.0.tar.gz 51.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cpm-pyoverview 0.1.0
File Interpreter ABI Platform
cpm_pyoverview-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 94.5 kB

Release files / cpm_pyoverview-0.1.0.tar.gz

Download URL cpm_pyoverview-0.1.0.tar.gz
Size 51.9 kB
Tags Source
SHA-256 checksum
How to use checksums
77d6d9293130dc01ccfa922eec9b323726769003a128f57a10cb029b9ef43bfb
BLAKE2b-256 checksum
How to use checksums
f24f3d813375baf23ca5b37c8287d83c7c5adde1a865cddf8fe66ea89dd03f53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release files / cpm_pyoverview-0.1.0-py3-none-any.whl

Download URL cpm_pyoverview-0.1.0-py3-none-any.whl
Size 42.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0370e3c177dd900539573a12b5b9f4db9105eaab5a39d564664c323da2d4cb0e
BLAKE2b-256 checksum
How to use checksums
d2c10e6f16a7a9acbe17bf4593aaf5326c44026ee6c06cce771741a3fb9060dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page