Skip to main content

Find dead Python code with Ruff's Rust parser

Project description

Ghostbuster

CI PyPI License

Ghostbuster finds dead Python code without starting Python. It is a Rust command-line tool built directly on Ruff's parser, syntax tree, source ranges, and line index.

The project takes Vulture's practical dead-code model as its behavioral reference while keeping a small Rust-native interface and a slightly more precise distinction between normal names and object members.

Install

With a prebuilt binary from a tagged GitHub release, or from PyPI under the ghostbuster-code distribution name:

uv tool install ghostbuster-code

The PyPI name is longer because the unrelated ghostbuster name was already taken. Both methods install the same ghostbuster executable and do not require Python at runtime. To build the full source checkout instead:

cargo install --git https://github.com/mazdak/ghostbuster --locked

Try it

cargo run -- src tests

Example output:

src/example.py:8: V103 unused function 'retired_handler' (60% confidence)
src/example.py:13: V201 unreachable code after 'return' (100% confidence)

Useful options:

ghostbuster --min-confidence 80 src
ghostbuster --exclude 'generated/**,vendor/**' .
ghostbuster --ignore-names 'visit_*,legacy_hook' src
ghostbuster --ignore-decorators '@app.route,@registry.*' src
ghostbuster --format json src > findings.json

Run ghostbuster --help for the complete interface. Explicit files are accepted regardless of their extension. Directories are walked recursively for .py files while respecting Git and standard ignore files.

Exit codes are designed for CI:

Code Meaning
0 No dead code found
1 A path could not be read or Python could not be parsed
2 Invalid command-line arguments or patterns
3 Dead code found

Findings

Code Finding Confidence
V101 Unused attribute 60%
V102 Unused class 60%
V103 Unused function 60%
V104 Unused import 90%
V105 Unused method 60%
V106 Unused property 60%
V107 Unused variable or argument 60% / 100%
V201 Unreachable code 100%

Ghostbuster understands definitions and loads across all input files in one run. It also handles common dynamic-Python signals such as __all__, getattr, hasattr, decorators, properties, dunder conventions, pytest entry points, type comments, dynamic format strings, Vulture's packaged protocol whitelists, and # noqa comments. Source files support Python's UTF-8 BOM plus common PEP 263 encodings, including Latin-1, Macintosh encodings, and numeric cpNNN code pages. F401 suppresses V104 and F841 suppresses V107, so existing Ruff suppressions remain useful.

Reachability covers dead tails after return, raise, break, and continue; constant branches; non-terminating while loops; terminal if, try, and exhaustive match branches; and nested suites. Ruff's AST truthiness handles literals, with Vulture-compatible short-circuit evaluation for constant and, or, and not expressions.

Why Ruff rather than a new parser?

Python syntax evolves quickly and source positions are easy to get subtly wrong. Ghostbuster uses the same Rust crates as Ruff and ty for parsing, AST traversal, UTF-8 byte ranges, Unicode columns, CRLF lines, and BOM handling. The five required crates are checked into vendor/ruff and pinned to one upstream Git revision, so builds do not silently switch parser implementations.

Ghostbuster itself only implements the dead-code policy that those projects do not expose as a standalone public API. Pulling in ty's full database, module resolver, and type checker would make a simple scanner much larger without replacing that policy layer.

Vulture compatibility evaluation

The data-driven corpus in tests/vulture is derived from Vulture's upstream tests and pins the exact source revision. It contains 46 cases: eight compare the complete result and collectively cover V101–V107 plus V201; the other 38 project one diagnostic category so a focused reachability test does not fail because an unrelated function in its snippet is also unused.

Ghostbuster deliberately preserves Vulture's project-wide bare-name behavior, which keeps the compatibility oracle stable across modules. Its precision improvement is narrower: normal names and object members live in separate namespaces, so a bare function call does not automatically mark every same-named method alive. Intentional differences are documented separately from missing compatibility behavior.

Development

Ghostbuster pins the same Rust 1.97 toolchain currently used by Ruff. The required checks are:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-targets --all-features
cargo check --workspace --all-targets --all-features --locked --offline

The minimum supported Rust version is 1.95. The pinned 1.97 toolchain supplies the formatter and Clippy version used by CI. See CONTRIBUTING.md for the complete development workflow.

  • Ruff source revision: f34ad603f07c766f9c4941a2f23ae88c84812c93
  • Vulture source revision: 2c21cb0ae2afa657e36f6a397cb573608a65d79e

Ghostbuster is intentionally not a crates.io package: its Ruff internals are pinned path dependencies. Build or install it from a complete source checkout, use the platform wheels on PyPI, or download a native release archive.

License

Ghostbuster is MIT licensed. Vendored Ruff code and Vulture-derived test data retain their upstream MIT notices. See THIRD_PARTY.md for provenance and THIRD_PARTY.html for the complete generated dependency notices shipped with releases.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

ghostbuster_code-0.1.0-py3-none-win_amd64.whl (1.9 MB view details)

Uploaded Python 3Windows x86-64

ghostbuster_code-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

ghostbuster_code-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ghostbuster_code-0.1.0-py3-none-macosx_11_0_arm64.whl (1.8 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

ghostbuster_code-0.1.0-py3-none-macosx_10_12_x86_64.whl (1.9 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

File hashes

Hashes for ghostbuster_code-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 692385bcf297ff449cc2f0d54e93b1f9c2f0f77a5344ca3062250e84e9bb46b5
MD5 42f1590ec7a7970ce32c3bdfd2ea0cc9
BLAKE2b-256 cc73e907c87854982dfe05c3b9bb8a694ca4862071922648a846bdab5d8fc38d

See more details on using hashes here.

Provenance

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

Publisher: release.yml on mazdak/ghostbuster

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

File details

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

File metadata

File hashes

Hashes for ghostbuster_code-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 007fc2cd30dba9eafd9b31629cae9223c89d64f55ea9f5c13100c5b7c596ed87
MD5 d98f67262d23dad49efe11abf9ec64d4
BLAKE2b-256 01bf83e3da80107df179662f19a4a57dc73dd608eaf5756794bab4d3daef5833

See more details on using hashes here.

Provenance

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

Publisher: release.yml on mazdak/ghostbuster

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

File details

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

File metadata

File hashes

Hashes for ghostbuster_code-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d8a3aac096dbdf43a2095224d3c990e0248dc7b086c7308ec59788f81937e575
MD5 5b9608d739fff6679b0ede3634192462
BLAKE2b-256 779e5dcc8705f53ea0c6994940fddbefdb007eae582db846b44178db8acc44e5

See more details on using hashes here.

Provenance

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

Publisher: release.yml on mazdak/ghostbuster

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

File details

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

File metadata

File hashes

Hashes for ghostbuster_code-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 59fd2b57366e779eb27b7bdd3edc49b6dcb510cd924117106a2386ce298ecda2
MD5 3ca15273677b532f01faeca94624b908
BLAKE2b-256 01f4ecf67f1827389a4a8d1c3c6893abb6a1862572d018043964bd6d4374151c

See more details on using hashes here.

Provenance

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

Publisher: release.yml on mazdak/ghostbuster

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

File details

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

File metadata

File hashes

Hashes for ghostbuster_code-0.1.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 81878ffcd015f9c36a413b75ce6a0b6136fa0430cdf2ba878170e9be9e236276
MD5 87c322776be03b3b19c24d19f4876f45
BLAKE2b-256 e075e470bbaa45ccf6de84e99b9026625ce0baf0330f77624b1a7e34e3040e2c

See more details on using hashes here.

Provenance

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

Publisher: release.yml on mazdak/ghostbuster

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