Skip to main content

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.

Metadata

Release files for ghostbuster-code 0.1.0

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

Built distributions (wheels)

Table of built distributions (wheels) for ghostbuster-code 0.1.0
File
ghostbuster_code-0.1.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
ghostbuster_code-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
ghostbuster_code-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
ghostbuster_code-0.1.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
ghostbuster_code-0.1.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 9.5 MB

Release files / ghostbuster_code-0.1.0-py3-none-win_amd64.whl

Download URL ghostbuster_code-0.1.0-py3-none-win_amd64.whl
Size 1.9 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
692385bcf297ff449cc2f0d54e93b1f9c2f0f77a5344ca3062250e84e9bb46b5
BLAKE2b-256 checksum
How to use checksums
cc73e907c87854982dfe05c3b9bb8a694ca4862071922648a846bdab5d8fc38d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 21, 2026.

Transparency log

Release files / ghostbuster_code-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ghostbuster_code-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.0 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
007fc2cd30dba9eafd9b31629cae9223c89d64f55ea9f5c13100c5b7c596ed87
BLAKE2b-256 checksum
How to use checksums
01bf83e3da80107df179662f19a4a57dc73dd608eaf5756794bab4d3daef5833
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 21, 2026.

Transparency log

Release files / ghostbuster_code-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL ghostbuster_code-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.9 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
d8a3aac096dbdf43a2095224d3c990e0248dc7b086c7308ec59788f81937e575
BLAKE2b-256 checksum
How to use checksums
779e5dcc8705f53ea0c6994940fddbefdb007eae582db846b44178db8acc44e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 21, 2026.

Transparency log

Release files / ghostbuster_code-0.1.0-py3-none-macosx_11_0_arm64.whl

Download URL ghostbuster_code-0.1.0-py3-none-macosx_11_0_arm64.whl
Size 1.8 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
59fd2b57366e779eb27b7bdd3edc49b6dcb510cd924117106a2386ce298ecda2
BLAKE2b-256 checksum
How to use checksums
01f4ecf67f1827389a4a8d1c3c6893abb6a1862572d018043964bd6d4374151c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 21, 2026.

Transparency log

Release files / ghostbuster_code-0.1.0-py3-none-macosx_10_12_x86_64.whl

Download URL ghostbuster_code-0.1.0-py3-none-macosx_10_12_x86_64.whl
Size 1.9 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
81878ffcd015f9c36a413b75ce6a0b6136fa0430cdf2ba878170e9be9e236276
BLAKE2b-256 checksum
How to use checksums
e075e470bbaa45ccf6de84e99b9026625ce0baf0330f77624b1a7e34e3040e2c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

5 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