Skip to main content

Find unused files, dependencies, and public symbols in Python projects

Project description

chokkin

日本語

Find unused files, dependencies, and public symbols in Python projects.

chokkin is a reachability analyzer for whole Python projects — a Knip-like experience for Python. It builds a project-wide graph from your manifests, source code, and tool configs, then reports what nothing reaches: run uvx chokkin with zero configuration, and tighten things up with precise settings and CI integration as you go.

[!NOTE] Status: v0.1 alpha. chokkin runs the full analysis pipeline (steps 1–13) by default: unused files, dependencies, and symbols with built-in reporters (default, compact, json, markdown), plus --explain, --trace, and --fix. Use --probe for steps 1–4 summary only. The §17 CHK002 false-positive gate passed after Phase 1.5 (make oss-metrics ARGS=--gate). PyPI v0.1 tag awaits Trusted Publishing setup.

Why chokkin?

Existing tools each cover one slice of the problem:

Ruff     : per-file, syntax-level linting
Vulture  : Python AST-based dead code detection
deptry   : consistency between dependency manifests and imports
chokkin    : unused files, dependencies, and public symbols from the whole project graph

chokkin is not a style/lint tool. It answers a different question: starting from your entry points, what can actually be reached — and what is just sitting there? It reads pyproject.toml, requirements files, uv/Poetry lockfiles, and framework/tool configs (Django, FastAPI, pytest, tox, nox, pre-commit, GitHub Actions, …) to build that picture.

Quick start

uvx chokkin

No configuration needed. On first run, chokkin discovers your manifests (pyproject.toml, setup.cfg, setup.py, requirements*.txt, uv.lock), infers your layout (src/flat, tests, scripts, docs), infers entry points, builds the import graph, and reconciles it against your declared dependencies:

chokkin 0.1.0

Project: acme-api
Config : pyproject.toml
Mode   : auto, production=false

Unused dependencies  3
  boto3          pyproject.toml:18  declared in [project.dependencies], no reachable import found
  rich           pyproject.toml:25  only used by scripts/dev.py; move to dependency-groups.dev
  python-dotenv  pyproject.toml:29  no import/config/binary usage found

Missing dependencies  1
  yaml -> PyYAML  src/acme/config.py:3  imported but not declared

Unused files  2
  src/acme/legacy.py        no path from any entry point
  src/acme/old_handlers.py  no path from any entry point

Unused exports  4
  src/acme/utils.py:12  function legacy_slugify
  src/acme/auth.py:44   class OldTokenBackend

Summary: 10 issues

What it checks

Code Issue Description Default severity
CHK001 unused_file Python file not reachable from any entry point warning
CHK002 unused_dependency declared in a manifest, but no import/config/binary usage found error
CHK003 missing_dependency imported, but not declared directly in any manifest error
CHK004 transitive_dependency imported directly, but only available via another dependency error
CHK005 misplaced_dependency runtime code uses a dev-group dependency, or a test-only dep is in main warning
CHK006 unused_export public symbol not referenced from outside its module warning
CHK007 unused_reexport re-export (e.g. in __init__.py) not referenced internally library: info / app: warning
CHK008 unlisted_binary CLI used by tox/nox/pre-commit/CI without a declared dependency warning
CHK009 duplicate_dependency declared in multiple of main/dev/optional warning
CHK010 unresolved_import import that resolves to neither first-party, third-party, nor stdlib warning

Because any module top-level name is importable in Python, unused_export starts out as a preview rule (info-level in library mode) rather than a hard error.

CLI

uvx chokkin
uvx chokkin --production
uvx chokkin --strict
uvx chokkin --no-exit-code
uvx chokkin --include CHK002,CHK003
uvx chokkin --exclude CHK006
uvx chokkin --reporter json
uvx chokkin --reporter markdown
uvx chokkin --confidence likely
uvx chokkin --fix
uvx chokkin --fix --dry-run
uvx chokkin --explain CHK002:boto3
uvx chokkin --trace src/acme/legacy.py
uvx chokkin --probe              # steps 1–4 summary only
uvx chokkin --init                # v0.2
uvx chokkin --reporter sarif      # v0.2

Key flags:

  • --production — drop dev/test/docs/lint/type contexts and judge reachability from runtime context only. Dev-only files and dependencies are no longer reported, and "unused in production" becomes strict.
  • --strict — direct imports of transitive dependencies always error, workspace members must declare their own dependencies, unused environment-marker dependencies error, and maybe-confidence issues are shown.
  • --no-exit-code — exit 0 even when issues are found (config/CLI errors still exit 2, internal errors 3). Useful during adoption and for GitHub Actions summaries.
  • --explain / --trace — show why an issue was reported / why a file is considered reachable. These are the intended path for investigating and reporting false positives.

Exit codes are fixed for CI:

0: no reportable issues
1: issues found
2: CLI/config error
3: internal error

Configuration

Zero config is the default. When you need precision, configure [tool.chokkin] in pyproject.toml (standalone chokkin.toml / .chokkin.toml are also accepted). chokkin --init appends a starter [tool.chokkin] reflecting what auto-discovery found.

[tool.chokkin]
entry = [
  "src/acme/__main__.py",
  "src/acme/asgi.py:application",
  "manage.py",
]
project = [
  "src/**/*.py",
  "tests/**/*.py",
  "scripts/**/*.py",
]
mode = "auto"             # auto | app | library
production = false
target_version = "py311"  # Python version of the analyzed project
respect_gitignore = true
confidence = "likely"     # certain | likely | maybe
exclude = [
  ".venv/**",
  "build/**",
  "dist/**",
  "**/__pycache__/**",
]

[tool.chokkin.dependencies]
dev_groups = ["dev", "test", "tests", "lint", "docs"]
runtime_groups = ["server", "worker"]
type_groups = ["types", "typing", "mypy"]

# distribution name -> import name(s), for cases the bundled map doesn't cover
[tool.chokkin.package_module_map]
"PyYAML" = ["yaml"]
"Pillow" = ["PIL"]

# CLI name -> distribution name, used by CHK008/CHK002 binary-usage checks
[tool.chokkin.binary_map]
"sphinx-build" = "Sphinx"

[tool.chokkin.plugins]
pytest = true
django = true
fastapi = true

Modes

mode = "auto" picks one of:

  • app mode — there's a clear entry (console_scripts, manage.py, asgi.py, wsgi.py, app.py). Unused files are reported aggressively.
  • library mode — a [project] name with a package and no clear entry. Public modules may be imported by external users, so unused files/exports are reported at low confidence (or as info). For serious unused-file detection in a library, declare entry explicitly.
  • workspace mode — multiple pyproject.toml files or tool.uv.workspace.members. Each member is analyzed separately (per-member [tool.chokkin.workspaces.<name>] config is supported), sharing the workspace lockfile.

Dependency contexts

Dependencies and files are both assigned contexts (runtime / dev / test / docs / lint / type / optional extras). That's what powers CHK005: import pytest in tests/ with pytest in your dev group is fine; the same import in src/ is a misplaced dependency. TYPE_CHECKING-only imports are type-context, and try: import orjson / except ImportError is treated as optional rather than missing.

Plugins

Frameworks reference modules through strings and decorators, which pure import analysis can't see. Plugins close that gap by adding entry files, string/module references, and binary usage:

  • v0.1: pytest, django, fastapi/uvicorn
  • v0.2+: flask, celery, tox, nox, pre-commit, github-actions, sphinx, mkdocs, alembic

For example, the Django plugin treats INSTALLED_APPS / MIDDLEWARE / ROOT_URLCONF strings as module references and migrations/** as framework-used; the FastAPI plugin treats @router.get-decorated handlers as externally used.

Suppressing issues

Inline and file-level ignores:

from legacy import old_api  # chokkin: ignore[CHK003]

# chokkin: file-ignore[CHK006]   (at the top of a file)

Config ignores, keyed by rule code (globs over distribution names, paths, or path:symbol):

[tool.chokkin.ignore]
CHK001 = ["src/acme/generated/**/*.py"]
CHK002 = ["boto3", "google-cloud-*"]
CHK006 = ["src/acme/public_api.py:*"]

For large existing projects, a baseline freezes current issues so CI only fails on new ones (v0.2):

uvx chokkin --update-baseline
uvx chokkin --baseline chokkin-baseline.json

Installation

chokkin is a single Rust binary shipped inside a Python wheel (prebuilt for Linux/macOS/Windows), so all of these work without a Rust toolchain:

uvx chokkin        # run without installing
pipx run chokkin
pip install chokkin

chokkin never executes your project's code — analysis is fully static. It also doesn't require your project's virtualenv: if .venv exists it is read for dist-info metadata (METADATA, top_level.txt, RECORD, entry_points.txt), otherwise manifests, lockfiles, and bundled maps are used.

Contributing

See CONTRIBUTING.md. The full design specification (analysis engine, import resolution strategy, roadmap) is in docs/dev/spec.ja.md (Japanese).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chokkin-0.1.0.tar.gz (339.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

chokkin-0.1.0-py3-none-win_amd64.whl (2.3 MB view details)

Uploaded Python 3Windows x86-64

chokkin-0.1.0-py3-none-musllinux_1_2_x86_64.whl (2.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

chokkin-0.1.0-py3-none-musllinux_1_2_aarch64.whl (2.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

chokkin-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

chokkin-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

chokkin-0.1.0-py3-none-macosx_11_0_arm64.whl (2.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

chokkin-0.1.0-py3-none-macosx_10_12_x86_64.whl (2.4 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file chokkin-0.1.0.tar.gz.

File metadata

  • Download URL: chokkin-0.1.0.tar.gz
  • Upload date:
  • Size: 339.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for chokkin-0.1.0.tar.gz
Algorithm Hash digest
SHA256 45263c3f0c27336f684d6182fb2f39de48228aafb1a55125020e4a0be0538f9f
MD5 b7d08487a630ebe090c80048e1a432be
BLAKE2b-256 0111286e084404ef80d6fd20fc8da21220278ac89e2b99236d749792a64caa54

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0.tar.gz:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: chokkin-0.1.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for chokkin-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 8966c6100c6c1179c667e5b4cf96746938e635f4dfa9477aa736dafbb7d3e6f3
MD5 03f3bd8eea228c7830eb2d41a328ae57
BLAKE2b-256 8cbbeb95851b5ea580a5314ba0a70db05fc4a17ecaf06b459f947d816e0d2ad4

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-win_amd64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for chokkin-0.1.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e7b5682c3c29486f7ceb44a77c31a6b589eba6187a400e39295ac6e40e62a9c3
MD5 39f7676863ad17a4bc7c5f231a741525
BLAKE2b-256 004c5c838058381ed983b932741d20f616d25b4fa3a75a590e67516e86c31e80

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for chokkin-0.1.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a0416d38dff0003c0d49652de90bf631bafa7fdc82a30d0d3a1487e3f87c3878
MD5 8f2f1783c8039b97dd641e9563e1f11d
BLAKE2b-256 d0b57bbe56bef6fe3175ece17b3f4920eb04bfeede529477d1b3446bec8671d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-musllinux_1_2_aarch64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for chokkin-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a7d55a0c3a87569f8e14337f2b5519ea5e6d2ccd598a834af65038486bb31f81
MD5 afe917cbff47000f5ecd01624c912f94
BLAKE2b-256 1ae5c698ab4afc485633b5d8ec658a3c6c842a8d8580d6febc79ff49de7d0f8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for chokkin-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ec56124089f58059002acc9e537259540b5cdb60db7af2747d379ce1e68ec6e7
MD5 f6ddc5c7506b9d8731cddae99f0585e1
BLAKE2b-256 1ec6ee344d4a71c060e9673302e61f07b8cf64deb78650cb21a88aaddb1cd166

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chokkin-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3da5f0762eb2b14d55353302b957e120a77c41767d880b9a5ea57a34d91f79d6
MD5 fb1518aef45e8eb1b6ac4e5e8fc2f603
BLAKE2b-256 31aea74412244f8095481360c5741d8984bbeba7b1a2ca88575454316bb0c2c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chokkin-0.1.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for chokkin-0.1.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 11556396bc040921912b89a4ff032fb03adc403620159a330bf893baaba7e86a
MD5 060689838f41441ce19e41335ae17791
BLAKE2b-256 5c25e3aef71e52379b3656712565419cb922ca2a1bf9bd462f9dd891ec3657b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for chokkin-0.1.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on watany-dev/chokkin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page