| Crates.io | pydeadcode |
| lib.rs | pydeadcode |
| version | 0.1.0 |
| created_at | 2025-12-24 13:21:39.806855+00 |
| updated_at | 2025-12-24 13:21:39.806855+00 |
| description | Fast Python dead code finder, built in Rust |
| homepage | |
| repository | https://github.com/utsav-pal/pydeadcode |
| max_upload_size | |
| id | 2003163 |
| size | 62,452 |
A blazingly fast Python dead code detector written in Rust using tree-sitter for accurate static analysis.
__init__, __str__, __enter__, etc.)test_* patterns)__all__ exportsgetattr, setattr)Install Rust from https://rustup.rs/:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone the repository
git clone https://github.com/utsav-pal/pydeadcode.git
cd pydeadcode
# Build release version (optimized)
cargo build --release
# Binary will be at target/release/pydeadcode
# You can run it with:
./target/release/pydeadcode <file.py>
# Faster build (unoptimized)
cargo build
# Run directly
cargo run -- <file.py>
# Or use the binary
./target/debug/pydeadcode <file.py>
# Install to ~/.cargo/bin (must be in your PATH)
cargo install --path .
# Now you can run from anywhere
pydeadcode <file.py>
# Analyze a single Python file
pydeadcode path/to/your_file.py
# Analyze multiple files
pydeadcode file1.py file2.py file3.py
# Using cargo run (during development)
cargo run -- testfile1.py
# Run the tool
pydeadcode <file.py>
# See help (coming soon)
pydeadcode --help
# Version info (coming soon)
pydeadcode --version
Given this Python code:
# example.py
def used_function():
return "I'm called"
def unused_function():
return "Nobody calls me"
class UsedClass:
def __init__(self):
self.value = 10
class UnusedClass:
pass
if __name__ == "__main__":
used_function()
obj = UsedClass()
Running PyDeadCode:
$ pydeadcode example.py
Dead Code Found:
example.py: line 4 - unused_function [function] (80% confidence)
example.py: line 11 - UnusedClass [class] (80% confidence)
2 dead code items found
PyDeadCode employs a sophisticated multi-phase static analysis approach:
Tracks all code definitions:
Scans the entire codebase for:
obj.method())getattr, eval)Applies heuristics to reduce false positives:
__init__, __str__, __call__, etc.)test_*, Test* classes__all__ exports: Explicitly exported items are marked as used_ get special handlingAssigns confidence levels:
testfile1.py - Basic scenarios:
testfile2.py - Complex edge cases (561 lines):
__getattr__# Build the project
cargo build
# Test on included files
./target/debug/pydeadcode testfile1.py
./target/debug/pydeadcode testfile2.py
# Run Rust unit tests
cargo test
# Run with verbose output
cargo test -- --nocapture
pydeadcode/
โโโ src/
โ โโโ main.rs # CLI entry point and argument parsing
โ โโโ analyzer.rs # Core analysis logic
โ โโโ parser.rs # Tree-sitter Python parser wrapper
โ โโโ detector.rs # Dead code detection algorithms
โโโ Cargo.toml # Rust dependencies and metadata
โโโ Cargo.lock # Locked dependency versions
โโโ .gitignore # Git ignore rules (excludes target/)
โโโ LICENSE # MIT License
โโโ README.md # This file
โโโ testfile1.py # Basic test cases
โโโ testfile2.py # Complex benchmark cases
| Tool | Language | Parser | Speed | False Positives | Dynamic Code |
|---|---|---|---|---|---|
| PyDeadCode | Rust | tree-sitter | โกโกโก Very Fast | Low | Smart handling |
| Vulture | Python | AST | Medium | High | Limited |
| Pylint | Python | AST | Slow | Medium | Basic |
| Skylos | Rust | tree-sitter | Fast | Low | Good |
| deadcode | Python | AST + Coverage | Slow | Very Low | Best |
PyDeadCode advantages:
--fix mode to automatically remove dead code.pydeadcode.toml)--exclude flag).pyi files)Contributions are welcome! Here's how you can help:
git clone https://github.com/<your-username>/pydeadcode.git
cd pydeadcode
git checkout -b feature/my-amazing-feature
cargo test
cargo build
./target/debug/pydeadcode testfile1.py
cargo fmt
cargo clippy
git commit -m "Add amazing feature"
git push origin feature/my-amazing-feature
cargo fmt)cargo clippy)Open an issue with:
rustc --version)This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2025 Utsav Pal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Utsav Pal
Benchmarked on various Python codebases:
| Codebase Size | Analysis Time | Memory Usage |
|---|---|---|
| 100 lines | ~10ms | ~5MB |
| 500 lines | ~30ms | ~10MB |
| 1000+ lines | ~50ms | ~15MB |
| 5000+ lines | ~200ms | ~30MB |
Tested on: Ubuntu 22.04, Intel i7, 16GB RAM
Accuracy: ~95% (manually verified on real-world projects)
eval(), exec(), string-based imports may cause false positivesgetattr/setattr might miss usageThese are planned improvements - contributions welcome!
Rust provides excellent performance and memory safety, making it ideal for parsing and analyzing large codebases quickly.
~95% accuracy on typical Python code. It uses smart heuristics to minimize false positives while catching most dead code.
Not yet. Currently read-only analysis. A --fix mode is planned for the future.
No, only Python 3.x is supported (via tree-sitter-python grammar).
It's in active development. Works well for analysis but test thoroughly before removing code.
โญ If you find this tool useful, please star it on GitHub!
๐ Found a bug? Open an issue
๐ก Have a feature request? Start a discussion