用途
Python Dead Code Detection 是一个用于检测和移除 Python 项目中死代码的技能,主要借助 vulture 和 ruff 两个工具完成分析。它覆盖未使用的变量、函数、类以及不可达分支,并针对框架约定造成的误报进行过滤。
主要能力
检测范围包括:
- 未使用的导入(ruff F401)
- 未使用的变量(ruff F841)
- 重复定义但未使用的名称(ruff F811)
- 未使用的函数和类(vulture)
- return/raise/break 之后的不可达代码(vulture)
关键特性包括:双工具策略,ruff 负责快速 lint 级检查,vulture 负责更深层分析;框架感知的误报过滤;置信度评分(vulture --min-confidence);支持白名单;可集成 CI/CD(GitHub Actions、pre-commit)。
安装
推荐使用 uv:
uv tool install vulture
uv tool install ruff
或使用 pip:
pip install vulture ruff
验证安装:
uv run vulture --version 2>/dev/null || vulture --version
uv run ruff --version 2>/dev/null || ruff --version
使用方式
Ruff 快速检查:
ruff check [target] --select F401
ruff check [target] --select F841
ruff check [target] --select F811
ruff check [target] --select F401,F811,F841
ruff check [target] --select F401 --fix
ruff check [target] --select F401 --fix --diff
Vulture 深度检测:
vulture [target]
vulture [target] --min-confidence 80
vulture [target] --min-confidence 90
vulture [target] whitelist.py --min-confidence 80
vulture [target] --exclude "venv,__pycache__,.git,migrations"
vulture [target] --min-confidence 80 --sort-by-size
结果分类
可将发现分为:未使用导入(ruff F401)、未使用变量(ruff F841)、重复定义未使用(ruff F811)、未使用函数(vulture)、未使用类(vulture)、未使用属性(vulture)、不可达代码(vulture)。
Vulture 输出示例:
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)
置信度含义:90-100% 几乎确定是死代码;80-89% 很可能,值得调查;60-79% 可能,需要检查动态使用。
误报处理
框架约定可能导致误报,以下模式通常不是死代码:
- Django:urls.py 字符串路径引用的视图、ORM 访问的模型字段、@receiver 信号处理器、管理命令、@admin.register 注册的类、MIDDLEWARE 引用的中间件、模板标签和过滤器、表单/序列化器字段
- FastAPI / Flask:@app.get/@app.post 路由处理器、Depends() 依赖注入函数、@app.on_event 事件处理器、异常处理器
- pytest:@pytest.fixture 装饰的夹具、conftest 夹具、parametrize 参数、pytest_* 插件钩子
- click / typer:@cli.command() 命令、回调函数、参数回调
- 通用:all 导出、init/str/repr 等 dunder 方法、getattr/importlib 动态访问、抽象方法实现、Celery @app.task/@shared_task 任务、Pydantic 模型字段和验证器
可创建白名单文件自动生成:
vulture [target] --make-whitelist > whitelist.py
然后审查并保留有意的条目。
配置
ruff(pyproject.toml):
[tool.ruff.lint]
select = ["F401", "F811", "F841"]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"conftest.py" = ["F401"]
"*.pyi" = ["F401"]
vulture(pyproject.toml):
[tool.vulture]
min_confidence = 80
exclude = [
"venv/",
".venv/",
"__pycache__/",
"migrations/",
"node_modules/",
]
paths = ["src/", "app/"]
清理工作流
按最安全优先的顺序应用移除:
- 未使用导入(最安全):用 ruff 自动修复
ruff check [target] --select F401 --fix,验证python -c "import mymodule"仍可用。 - 未使用变量:审查
ruff check [target] --select F841,解包时用_替代。 - 未使用函数和类(风险最高):针对 vulture 置信度 >= 80% 的发现,搜索动态使用、检查 all 导出、检查装饰器、检查字符串引用,确认无用后删除。
- 不可达代码:移除无条件 return、raise、break 或 continue 之后的代码块。
CI/CD 集成
GitHub Actions 示例:
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 示例:
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"]
Makefile 目标:
.PHONY: dead-code
dead-code:
ruff check . --select F401,F811,F841
vulture src/ --min-confidence 80
常见模式
仅检查导入(最快):ruff check . --select F401,用于 CI 严格导入卫生。
完整审计:先 ruff check . --select F401,F811,F841,再 vulture . --min-confidence 80 --exclude "venv,migrations,__pycache__",最后交叉核对并过滤误报。
Monorepo:分别扫描各包 vulture packages/core/ --min-confidence 80,或使用共享白名单。
库开发:保守起见使用 vulture src/mylib/ --min-confidence 90,并排除 init.py 的重导出。
故障排查
误报太多:提高 --min-confidence 到 90,创建白名单,使用 --exclude 排除生成代码、迁移、第三方代码。
Vulture 漏文件:确认目标路径正确,可用调试命令查看扫描内容。
Ruff 未检测到未使用导入:检查 F401 是否启用,可强制启用。
两个工具冲突:用 ruff 处理导入(可自动修复),用 vulture 处理函数/类(需人工审查),展示前去重。
适用场景与限制
适用于代码清理、CI 质量门禁、库开发、monorepo 多包扫描。需要注意:公共 API 符号可能被标记为未使用;动态引用、框架约定和字符串引用容易造成误报,需结合白名单和人工审查。具体功能、收费、价格、平台或效果等资料中未提供的内容,暂未提供。