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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cpm_pyoverview-0.1.0.tar.gz.
File metadata
- Download URL: cpm_pyoverview-0.1.0.tar.gz
- Upload date:
- Size: 51.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77d6d9293130dc01ccfa922eec9b323726769003a128f57a10cb029b9ef43bfb
|
|
| MD5 |
23195b1f8efdad7f8beb3d7d9dd4979b
|
|
| BLAKE2b-256 |
f24f3d813375baf23ca5b37c8287d83c7c5adde1a865cddf8fe66ea89dd03f53
|
Provenance
The following attestation bundles were made for cpm_pyoverview-0.1.0.tar.gz:
Publisher:
publish.yml on cprima/pyoverview
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpm_pyoverview-0.1.0.tar.gz -
Subject digest:
77d6d9293130dc01ccfa922eec9b323726769003a128f57a10cb029b9ef43bfb - Sigstore transparency entry: 2322270171
- Sigstore integration time:
-
Permalink:
cprima/pyoverview@851aeeed741535447212190ae5b7cd330a2cec88 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/cprima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@851aeeed741535447212190ae5b7cd330a2cec88 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cpm_pyoverview-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cpm_pyoverview-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0370e3c177dd900539573a12b5b9f4db9105eaab5a39d564664c323da2d4cb0e
|
|
| MD5 |
180aac1be662fb8ebba2ef5fa000fcb6
|
|
| BLAKE2b-256 |
d2c10e6f16a7a9acbe17bf4593aaf5326c44026ee6c06cce771741a3fb9060dd
|
Provenance
The following attestation bundles were made for cpm_pyoverview-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on cprima/pyoverview
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpm_pyoverview-0.1.0-py3-none-any.whl -
Subject digest:
0370e3c177dd900539573a12b5b9f4db9105eaab5a39d564664c323da2d4cb0e - Sigstore transparency entry: 2322270231
- Sigstore integration time:
-
Permalink:
cprima/pyoverview@851aeeed741535447212190ae5b7cd330a2cec88 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/cprima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@851aeeed741535447212190ae5b7cd330a2cec88 -
Trigger Event:
release
-
Statement type: