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:
- Parse (
parser.py, syntax-only, per file, viaast_visitors.py) →ParsedModule(internal only -- holds the retained AST tree). - Resolve (
project_resolver.pyorchestratingmodule_resolver.py,import_resolver.py,export_resolver.py,binding.py,symbol_table.py,entry_point_resolver.py) →ResolvedModule+ project-wide symbol table + dependency edges. - Reference (
reference_resolver.py, bounded type inference) → gradedresolved/probable/unresolvedusage 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-versionis metadata-plus-parsing only: stdlib-module classification always uses the running interpreter'ssys.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 andpyproject.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 fullsys.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)
| File | Size | Uploaded | |
|---|---|---|---|
| cpm_pyoverview-0.1.0.tar.gz | 51.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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