Dead Code Doesn't Have to Be a Guessing Game
You've probably inherited a Python codebase where nobody's sure what's still in use. Somewhere in there are functions nobody calls, imports nobody needs, and classes that haven't been touched since a sprint long forgotten. Removing them feels risky, so they linger. Vulture is a static analysis tool that scans your Python files and tells you which chunks of code look unused, attaching a confidence value to each one so you can decide what's actually safe to delete.
What It Does
Vulture analyzes Python programs to find unused code. Point it at a file or a directory, and it reports functions, classes, imports, attributes, variables, and properties that appear to be dead. It also detects unreachable code. The goal is cleaning up large codebases and catching errors—and if you run it against both your library and your test suite, it can surface untested code as well.
It's a static analyzer, which means it reads your source without executing it. It uses the same output syntax as pyflakes, so it slots neatly next to tools you may already have in your linting setup. Every finding comes with a confidence value between 60% and 100%, based on the type of code chunk. The README is refreshingly honest about the limits here: because Python is dynamic, Vulture will miss some dead code, and code that's only called implicitly might get flagged as unused. The confidence values below 100% are described as "very rough estimates"—not precision instruments.
Why It's Cool
-
Confidence values make the output actionable. Most dead-code tools hand you a flat list and let you sort out the noise. Vulture tells you how sure it is. Unreachable code and unused arguments get 100%. Imports get 90%. Attributes, classes, functions, methods, properties, and variables get 60%. That tiering lets you start with the findings you can trust.
-
--min-confidencegives you a dial. Run with--min-confidence 100and you'll only see code that's guaranteed unused within the files you analyzed. That's a safe starting point if you're nervous about breaking things. -
--sort-by-sizeprioritizes the payoff. Unused classes and functions are sorted by size, so you can tackle the biggest wins first instead of scrolling through a list of one-line leftovers. -
Whitelists handle false positives gracefully. The recommended fix for anything Vulture gets wrong is to generate a whitelist with
--make-whitelist, then include it in the scanned paths. You get valid Python syntax out of it—though the README notes you'll usually need to tweak it before it can actually run. The project also collects whitelists for common modules and packages, and accepts pull requests for more. -
It tells you to run it twice. After you delete dead code, run Vulture again—removing one unused function can expose others that were only reachable through it. That's a small detail, but it shows the tool was designed around real cleanup workflows.
-
It's fast and it tests itself. Static analysis means speed, and the project claims complete test coverage of its own code. You can also exclude whole files or directories with
--exclude, matched against absolute paths.
How to Try It
- Install it:
pip install vulture
- Run it against a script or a package:
vulture myscript.py
vulture myscript.py mypackage/
Or invoke it as a module:
python3 -m vulture myscript.py
- Start conservative if you're working in a codebase you don't fully know:
vulture myscript.py --min-confidence 100
- When you hit false positives, generate a whitelist and feed it back in:
vulture mydir --make-whitelist > whitelist.py
vulture mydir whitelist.py
The full source and documentation live at github.com/jendrikseipp/vulture.
Final Thoughts
Vulture isn't magic, and it doesn't pretend to be—the README says outright that dynamic Python will always leave some dead code undetected and some live code falsely flagged. What it offers is a sensible way to work within those limits: confidence values to triage, a minimum-confidence flag for safety, and whitelists for the inevitable exceptions. If you maintain a large Python codebase or want to find untested code by comparing your library against your tests, it's worth adding to your toolkit. Just plan on running it more than once.