用 pylock.toml 打通 pip、uv 与 PDM:PEP 751 锁文件实践

2026-07-22 20 预计阅读时间: 1 分钟
来源: realpython.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Python 一直不缺依赖管理工具,真正缺的是一份能跨工具交换的标准锁文件。PEP 751 定义了 pylock.toml,目标是让解析依赖和安装依赖成为两个可以分离的步骤:一个工具生成锁定结果,另一个兼容工具按照相同结果完成安装。

这意味着团队不必因为构建系统、开发环境或部署平台使用不同工具,就维护多份含义相近但格式互不兼容的锁文件。

pylock.toml 解决的不是“版本范围”,而是“安装结果”

普通依赖文件经常只描述允许范围:

httpx>=0.27,<1
rich>=13,<14

这份声明无法保证两次安装得到完全相同的版本。解析器会结合发布时间、Python 版本、操作系统和依赖关系,选择当时可用的候选包。

锁文件承担的是另一项职责:记录解析后的具体软件包、版本、构件及校验信息,使安装工具尽量避免重新求解依赖。标准化后的 pylock.toml 还允许兼容 PEP 751 的工具读取同一份结果,而不必理解某个工具的私有锁文件格式。

需要注意,标准格式不等于跨平台结果会自动出现。锁文件能覆盖哪些 Python 版本、操作系统和 CPU 架构,仍取决于生成命令、输入约束以及解析器能力。只在 Linux 和 Python 3.12 环境中生成并验证的文件,不应未经测试就被视为 Windows、macOS 或其他 Python 版本的可靠部署清单。

从 pip 生成一份标准锁文件

可以这样实践:创建一个空目录,并准备 requirements.in

mkdir pylock-demo
cd pylock-demo

cat > requirements.in <<'EOF'
httpx>=0.27,<1
rich>=13,<14
EOF

python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip lock -r requirements.in -o pylock.toml

Windows PowerShell 中激活虚拟环境可改为:

.venv\Scripts\Activate.ps1

这里要区分三类文件:

  • requirements.in 表达项目接受的版本范围,适合人工维护。
  • pylock.toml 保存解析后的安装计划,适合提交到版本库。
  • 虚拟环境是锁文件的实际安装目标,不应提交到版本库。

生成后,可以先检查文件头和被锁定的软件包:

sed -n '1,80p' pylock.toml

pip lock 的可用性和参数取决于本地 pip 版本,因此 CI 中应固定或明确最低 pip 版本,并执行 python -m pip lock --help 验证环境。生成命令也应在受控平台运行,避免开发者机器差异悄悄改变锁定结果。

用 uv 和 PDM 消费同一份锁定结果

PEP 751 的价值不只在于文件名统一,而在于兼容工具能够消费同一份锁定数据。可以在两个全新的虚拟环境中分别验证。

使用 uv 时,可以这样安装:

python -m venv .venv-uv
uv pip install --python .venv-uv/bin/python -r pylock.toml
.venv-uv/bin/python -c "import httpx, rich; print(httpx.__version__)"

Windows 上应把解释器路径替换为 .venv-uv\Scripts\python.exe

使用支持 PEP 751 的 PDM 版本时,可以这样指定锁文件:

python -m venv .venv-pdm
pdm install --venv .venv-pdm --lockfile pylock.toml

不同版本的 uv 和 PDM 对 pylock.toml 的支持范围及命令参数可能变化。把这些命令加入 CI 前,应先检查当前版本的帮助信息:

uv pip install --help
pdm install --help

跨工具测试的重点不是“命令返回了零”,而是确认工具没有重新解析出另一套版本。可以记录安装结果并进行比较:

uv pip freeze --python .venv-uv/bin/python | sort > uv-installed.txt
pdm run python -m pip freeze | sort > pdm-installed.txt
diff -u uv-installed.txt pdm-installed.txt

这段比较命令假设 PDM 当前运行环境就是刚才安装依赖的环境;如果项目配置不同,应显式激活目标虚拟环境后再执行 python -m pip freeze

CI 中把“生成”和“验证”分开

锁文件应由明确的更新流程生成,而普通构建只负责验证和安装。一个可改造的 CI 脚本如下:

#!/usr/bin/env bash
set -euo pipefail

python -m venv .ci-venv
python -m pip install --python .ci-venv/bin/python \
  --upgrade pip uv

uv pip install --python .ci-venv/bin/python -r pylock.toml
.ci-venv/bin/python -c "import httpx, rich"

更新依赖时,再单独运行:

python -m pip lock -r requirements.in -o pylock.toml
git diff -- pylock.toml

审查锁文件变化时,至少要关注新增和删除的软件包、版本跳跃、来源变化以及构件哈希变化。锁文件能够提高可复现性,但不能替代漏洞扫描、来源控制和制品签名验证。

采用前的检查清单

在团队中引入 pylock.toml,建议确认以下事项:

  • 生成端和安装端使用的工具版本都明确支持 PEP 751。
  • 锁文件覆盖生产环境所需的 Python 版本和目标平台。
  • CI 从干净环境安装,避免缓存或预装包掩盖问题。
  • 常规构建只消费锁文件,不在安装阶段静默更新它。
  • 依赖升级通过独立变更提交,并审查版本、来源和哈希差异。
  • 在 pip、uv、PDM 等实际使用的工具之间执行至少一次交叉安装测试。

PEP 751 并不会消除各工具在解析策略、缓存、工作区管理和发布流程上的差异。它提供的是一条稳定的交换边界:团队可以选择适合自己的解析器和安装器,同时用 pylock.toml 传递一份可审计的依赖安装结果。


相关推荐