plugins/python-development/skills/python-dead-code/SKILL.md
Detect and remove unused Python code using vulture and ruff. Covers unused imports, variables, functions, classes, and unreachable code. Framework-aware false positive handling for Django, FastAPI, pytest, click, and more. TRIGGER WHEN: cleaning up Python codebases, enforcing import hygiene, or integrating dead code checks into CI. DO NOT TRIGGER WHEN: the task is outside the specific scope of this component.
npx skillsauth add acaprino/anvil-toolset python-dead-codeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Detect and remove unused code in Python projects using vulture and ruff. Framework-aware analysis that distinguishes real dead code from convention-driven usage patterns.
What it detects
Key capabilities
--min-confidence)# Using uv (recommended)
uv tool install vulture
uv tool install ruff
# Or via pip
pip install vulture ruff
# Verify installation
uv run vulture --version 2>/dev/null || vulture --version
uv run ruff --version 2>/dev/null || ruff --version
# Unused imports (F401)
ruff check [target] --select F401
# Unused variables (F841)
ruff check [target] --select F841
# Redefined unused names (F811)
ruff check [target] --select F811
# All unused-code rules together
ruff check [target] --select F401,F811,F841
# Auto-fix safe removals (imports only)
ruff check [target] --select F401 --fix
# Preview what would be fixed
ruff check [target] --select F401 --fix --diff
# Full scan with default confidence (60%)
vulture [target]
# Higher confidence -- fewer false positives (recommended)
vulture [target] --min-confidence 80
# Very high confidence -- only obvious dead code
vulture [target] --min-confidence 90
# Scan with whitelist
vulture [target] whitelist.py --min-confidence 80
# Exclude specific paths
vulture [target] --exclude "venv,__pycache__,.git,migrations"
# Sort by confidence (highest first)
vulture [target] --min-confidence 80 --sort-by-size
Group results into these categories for structured reporting:
| Category | Source | Rule/Detection |
|----------|--------|----------------|
| Unused imports | ruff | F401 |
| Unused variables | ruff | F841 |
| Redefined-unused | ruff | F811 |
| Unused functions | vulture | unused function |
| Unused classes | vulture | unused class |
| Unused properties | vulture | unused property |
| Unreachable code | vulture | unreachable code |
src/utils.py:42: unused function 'calculate_tax' (60% confidence)
src/models.py:15: unused class 'LegacyUser' (90% confidence)
src/views.py:8: unused import 'render' (90% confidence)
These patterns are NOT dead code even if vulture flags them:
Django
urls.py via string paths@receiverhandle method)@admin.registerMIDDLEWARE settingFastAPI / Flask
@app.get, @app.post, etc.Depends()@app.on_event)pytest
@pytest.fixture (used by name injection)pytest_* functions)click / typer
@cli.command()General Python
__all__ exports__init__, __str__, __repr__, and other dunder methodsgetattr / importlib dynamic access@app.task or @shared_task# whitelist.py -- tell vulture these are intentionally used
# Django views (referenced via urls.py string paths)
index_view # unused function
detail_view # unused function
# pytest fixtures
db_session # unused function
mock_client # unused function
# Celery tasks
send_notification_email # unused function
# Signal handlers
on_user_created # unused function
Generate a whitelist automatically:
# Vulture can generate a whitelist from its findings
vulture [target] --make-whitelist > whitelist.py
Then review and keep only the intentional entries.
[tool.ruff.lint]
# Enable unused-code rules
select = ["F401", "F811", "F841"]
[tool.ruff.lint.per-file-ignores]
# Allow unused imports in __init__.py (re-exports)
"__init__.py" = ["F401"]
# Allow unused imports in conftest.py (fixtures)
"conftest.py" = ["F401"]
# Allow unused imports in type stubs
"*.pyi" = ["F401"]
[tool.vulture]
min_confidence = 80
exclude = [
"venv/",
".venv/",
"__pycache__/",
"migrations/",
"node_modules/",
]
paths = ["src/", "app/"]
# Symbols that vulture flags but are used dynamically
from myapp.models import * # noqa: F403 -- re-export
Apply removals in safest-first order:
# Auto-fix with ruff
ruff check [target] --select F401 --fix
# Or remove manually via editor
Verify: python -c "import mymodule" still works.
# Review each finding
ruff check [target] --select F841
For unpacking, replace with _:
# Before
x, y, z = get_coords() # z unused
# After
x, y, _ = get_coords()
For each vulture finding with >= 80% confidence:
grep -r "function_name" across the codebase__all__ exports: is it in a public API?@receiver, @app.task, @pytest.fixture, etc.Remove code blocks after unconditional return, raise, break, or continue.
name: Dead Code Check
on:
push:
branches: [main]
pull_request:
jobs:
dead-code:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- name: Check unused imports
run: uvx ruff check . --select F401,F841 --output-format github
- name: Check dead code (vulture)
run: uvx vulture src/ --min-confidence 90
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff
args: [--select, "F401,F841", --fix]
- repo: https://github.com/jendrikseipp/vulture
rev: v2.14
hooks:
- id: vulture
args: [--min-confidence, "90"]
.PHONY: dead-code
dead-code:
ruff check . --select F401,F811,F841
vulture src/ --min-confidence 80
ruff check . --select F401
Use in CI for strict import hygiene.
# Step 1: fast lint checks
ruff check . --select F401,F811,F841
# Step 2: deep analysis
vulture . --min-confidence 80 --exclude "venv,migrations,__pycache__"
# Step 3: cross-reference and filter false positives
# Scan specific packages
vulture packages/core/ --min-confidence 80
vulture packages/api/ --min-confidence 80
# Or scan all with shared whitelist
vulture packages/ whitelist.py --min-confidence 80
# Be conservative -- public API symbols may appear unused
vulture src/mylib/ --min-confidence 90
# Exclude __init__.py re-exports
ruff check src/mylib/ --select F401 --per-file-ignores "__init__.py:F401"
--min-confidence to 90--exclude for generated code, migrations, vendored code# Ensure target path is correct
vulture src/ tests/ --min-confidence 80
# Debug: list what vulture scans
vulture src/ --min-confidence 80 2>&1 | head -20
# Check if F401 is enabled
ruff check --show-settings | grep F401
# Force enable
ruff check . --select F401 --config "lint.select = ['F401']"
Ruff and vulture may flag the same import. Use ruff for imports (auto-fixable) and vulture for functions/classes (needs manual review). Deduplicate findings before presenting.
development
Quality gates for multi-reviewer code review pipelines: adversarial verification panel, completeness critic, reviewer pipeline conventions, and the context sharing pattern for parallel reviewers. TRIGGER WHEN: running /senior-review:team-review quality gates; running /senior-review:code-review Steps 4b/4c (adversarial verification and completeness check); consolidating or deduplicating findings from multiple parallel reviewers. DO NOT TRIGGER WHEN: single-reviewer style review without a consolidation phase, or generic team coordination (the upstream agent-teams skills cover that).
development
Knowledge base for pure-architecture decisions on when to unify duplicated logic into a shared abstraction versus leave it duplicated. Covers the canonical theory (Rule of Three, DRY/WET/AHA, Wrong Abstraction, Locality of Behaviour, Bounded Contexts, Tidy First options framing, CUPID vs SOLID), 12 essential-duplication patterns that justify unification, 12 wrong-abstraction patterns that justify inlining or decomposition, an operational decision frame, and a verified reading list. TRIGGER WHEN: the user is making an architectural decision about whether to centralize, extract, or remove a layer; reviewing an abstraction for premature generality; auditing scattered cross-cutting concerns; spawned by the abstraction-architect agent during /abstraction-architect:audit or as the Abstraction dimension of /senior-review:team-review or /senior-review:code-review; the user asks "should I extract this into a service" / "is this DRY enough" / "is this wrong abstraction". DO NOT TRIGGER WHEN: the task is code formatting and readability cleanup (use clean-code:clean-code), Python-specific refactoring with metrics (use python-development:python-refactor), generic dead-code removal (use senior-review:cleanup-dead-code), security review (use senior-review:security-auditor), or pure pattern-consistency review without an architecture lens (use senior-review:code-auditor).
development
Unified web frontend knowledge base covering CSS architecture, UX psychology, UI components, distinctive aesthetics, and interface design generation. TRIGGER WHEN: working on web styling, design systems, component decisions, responsive strategy, distinctive frontend aesthetics, or exploring multiple interface designs. DO NOT TRIGGER WHEN: the task is purely backend or unrelated to web frontend.
development
Stripe payments knowledge base - API patterns, checkout optimization, subscription lifecycle, pricing strategies, webhook reliability, Firebase integration, cost analysis, and revenue modeling. Loaded by stripe-integrator and revenue-optimizer agents; also consumable directly when the user asks for Stripe-specific patterns without needing an agent. TRIGGER WHEN: working with Stripe API (Payment Intents, Customers, Subscriptions, Checkout Sessions, Connect, webhooks, tax, usage-based billing), pricing strategy, or revenue modeling. DO NOT TRIGGER WHEN: payment work is non-Stripe (PayPal, Square, crypto) or the task is generic e-commerce unrelated to payments.