pre-commit 本身不检查 python 环境,因其钩子运行在隔离虚拟环境中,无法感知项目要求的 python 版本或依赖;需通过自定义脚本(如 check-env.py)显式校验版本与包,并配置为 script 类型钩子。

Pre-commit 钩子本身不执行环境检查(比如 Python 版本、依赖是否安装),它只负责在 git commit 前运行你配置的命令。真要做环境检查,得靠你自己写脚本或选对工具——pre-commit 只是调度器。
为什么 pre-commit 不能直接检查 Python 环境?
pre-commit 的每个钩子默认运行在隔离的虚拟环境中(由 pre-commit 自动管理),它看到的是钩子自身依赖的 Python 解释器,不是你项目期望的那个。比如你项目要求 Python>=3.10,但 pre-commit 可能用系统 Python 3.9 安装自己,然后照样跑钩子——完全感知不到你的项目约束。
- 钩子运行时的
PYTHONPATH、sys.executable和你本地开发环境无关 -
pre-commit不读取pyproject.toml中的requires-python字段 - 它也不检查
pip install -e .是否成功,更不管poetry install有没有报错
用自定义钩子做 Python 版本和依赖检查
把检查逻辑写成一个独立脚本(如 check-env.py),再通过 pre-commit 调用它。关键点:脚本必须显式使用你期望的 Python 解释器(比如 #!/usr/bin/env python3.11),且需在项目根目录下可执行。
- 脚本开头加
#!/usr/bin/env python3.11,并chmod +x check-env.py - 脚本里用
import sys校验sys.version_info,用import importlib.util检查关键包是否存在(如numpy) - 在
.pre-commit-config.yaml中配成entry: ./check-env.py,类型设为script - 避免用
shell: python check-env.py,否则会绕过 shebang,可能调错解释器
- repo: local
hooks:
- id: check-python-version
name: Check Python version >= 3.11
entry: ./check-env.py
language: script
pass_filenames: false
always_run: true
用 pre-commit-hooks 插件替代手写脚本
社区有现成方案,比如 pre-commit-hooks 包里的 check-executables-have-shebangs 虽不直接管 Python 版本,但配合 check-yaml、end-of-file-fixer 可以守住基础规范;更实用的是 pyproject-hooks 这类第三方库,它提供 check-poetry-lock 或 check-pdm-lock,能验证 lock 文件是否与 pyproject.toml 同步——这才是真正的“环境一致性”检查入口。
- 优先用
check-toml验证pyproject.toml语法,避免因格式错误导致后续工具失效 - 如果用
poetry,加poetry-check钩子(需单独 pip install),它会调poetry env info --path并比对pyproject.toml中的virtualenvs.in-project - 不要指望一个钩子搞定所有:版本检查、依赖安装、格式校验最好拆成不同钩子,失败时更容易定位
真正难的不是让 pre-commit “跑起来”,而是让它失败时给出明确提示——比如用户看到 python3.9 not supported 就该立刻明白要切 pyenv 版本,而不是去翻日志猜哪行错了。这需要你在检查脚本里输出清晰的 print() 和非零退出码,而且得测试它在 CI 和本地不同 shell 下都显示正常。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











