--require-virtualenv 是一个很实用但长期“缺测试”的开关:它能避免在非虚拟环境里误操作系统 Python。但因为几乎没覆盖测试,这个功能也一直比较难放心地文档化和维护。
- Issue: pypa/pip#12843
- PR: pypa/pip#13806
🔍 分析 (Analyze)
这类“安全护栏”功能最怕两种回归:
- 行为被悄悄改坏:比如 venv 探测逻辑在某个边缘场景失效,导致
--require-virtualenv没拦住。 - 新增子命令时没人注意 opt-in/opt-out:有些命令(如
help/debug)不应该被强制要求在 venv 内运行;另一些(如install/uninstall)则应该被拦住。没有测试约束的话,新命令很容易“默认值凑合用”,最后行为不一致。
因此,这次的目标不是改实现,而是把预期行为固定下来。
📍 定位 (Locate)
- 入口逻辑:
src/pip/_internal/cli/base_command.py(options.require_venv+ignore_require_venv+running_under_virtualenv()) - 命令注册表:
src/pip/_internal/commands/__init__.py(commands_dict) - 新增测试:
tests/unit/test_base_command.py
🛠️ 执行 (Execute)
- 增加单测覆盖“未处于 venv 时启用
--require-virtualenv”的退出码(VIRTUALENV_NOT_FOUND); - 增加单测覆盖“明确 opt-out 的命令仍可运行”(例如
pip help); - 增加一个矩阵测试:枚举
commands_dict中所有命令,断言每个命令的ignore_require_venv取值与预期表一致,从而强制未来新增/调整命令时必须显式做决定。
✅ 总结 (Summary)
这次贡献的价值点主要在“降低维护成本”:把 --require-virtualenv 的关键行为用测试锁住,既能避免未来回归,也能在新增子命令时让 opt-in/opt-out 的选择变成显式、可 review 的改动。