用 PEP 751 和 pylock.toml 统一 Python 依赖锁定

2026-07-22 27 预计阅读时间: 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.

预计阅读时间:7 分钟

Python 项目长期缺少一种跨工具的标准锁文件:requirements.txt 能固定版本,却难以完整表达依赖来源、哈希、环境标记和多平台候选包;Poetry、PDM、uv 等工具的专用锁文件又不能自然互换。PEP 751 引入标准化的 pylock.toml,目标是让生成锁文件与安装依赖不再绑定同一个工具。

requirements.txt 为什么不等于标准锁文件

典型的 requirements.txt 看起来很明确:

fastapi==0.115.12
uvicorn==0.34.2

但它本质上仍是一份 pip 风格的安装输入。即使加入哈希和环境标记,不同工具对文件内容、生成方式和扩展语法的理解也可能不同。

pylock.toml 则拥有标准化的数据结构,可以描述锁定的软件包、版本、制品、哈希、依赖关系以及适用环境。更重要的是,它把两个动作拆开了:

  • 锁定工具负责解析依赖并生成 pylock.toml
  • 安装工具读取同一文件,选择与当前平台和 Python 环境匹配的制品。
  • CI、容器构建和本地开发可以使用不同工具,但共享同一份依赖决策。

这里的“工具无关”并不表示所有工具会产生完全相同的解析结果,而是表示它们可以围绕同一种交换格式协作。

用 pip 或 uv 生成锁文件

下面是一套可以这样实践的最小项目。工具版本需要已经支持 PEP 751;如果现有环境中的命令无法识别 pylock.toml,应先升级对应工具。

创建 pyproject.toml

[project]
name = "lock-demo"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
  "httpx>=0.27,<1",
  "rich>=13,<15",
]

使用较新的 pip 生成锁文件:

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

也可以让 uv 根据同一个项目元数据生成 PEP 751 锁文件:

uv pip compile pyproject.toml -o pylock.toml

不同版本的工具可能调整参数名称,因此应在自动化脚本中固定 pip 或 uv 的版本,并通过下面的命令核对当前版本支持的选项:

python -m pip lock --help
uv pip compile --help

生成后,应把 pylock.toml 提交到版本库。修改 pyproject.toml 中的直接依赖时,重新生成锁文件,并在代码审查中同时检查这两个文件。

用另一种工具安装同一份锁定结果

标准格式真正有价值的地方,不是文件扩展名发生变化,而是安装端可以换工具。使用支持 PEP 751 的 uv,可以这样同步环境:

uv venv
uv pip sync pylock.toml

在采用 PDM 的项目中,可以这样实践:

pdm install --lockfile pylock.toml

运行前应使用 pdm install --help 确认所安装版本已经提供 PEP 751 锁文件支持。团队还应在 CI 中验证安装过程,避免开发机上的新版本工具生成了构建环境尚不能读取的字段。

一个简化的 CI 检查可以写成:

name: locked-dependencies

on:
  pull_request:
  push:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
        with:
          version: "0.7.x"
      - run: uv venv
      - run: uv pip sync pylock.toml
      - run: uv run python -c "import httpx, rich; print(httpx.__version__)"

请把示例中的 uv 版本改成团队验证过、明确支持所用 pylock.toml 结构的版本。生产项目还应执行完整测试,而不只是导入包。

迁移时不要直接删除 requirements.txt

requirements.txt 迁移可以分阶段完成:

  1. 把顶层依赖移入 pyproject.toml,明确 Python 版本范围。
  2. 使用固定版本的锁定工具生成 pylock.toml
  3. 在 CI 和容器构建中验证全新环境安装,而不是复用已有虚拟环境。
  4. 检查 Linux、macOS、Windows 或不同 CPU 架构是否需要不同锁文件。
  5. 等部署平台、扫描器和内部镜像流程都能读取新格式后,再移除旧文件。

PEP 751 允许采用 pylock.<name>.toml 形式,因此无法用一个锁文件覆盖全部目标环境时,可以维护用途明确的文件,例如 pylock.linux.tomlpylock.docs.toml。代价是更新工作增加,团队必须清楚每个文件对应的 Python 版本、平台和部署场景。

采用前的工程检查

pylock.toml 解决的是锁文件交换格式,不会自动解决所有供应链问题。落地时仍需确认以下事项:

  • 固定生成锁文件的工具版本,避免解析器升级造成大面积无关变更。
  • 在代码审查中检查版本变化、下载来源和哈希,而不是把锁文件当作不可读产物。
  • 使用全新环境测试安装,确保没有依赖本地缓存或未声明的软件包。
  • 明确锁文件覆盖的平台和 Python 版本;跨平台项目要验证条件依赖与二进制 wheel。
  • 保留依赖更新机器人、安全扫描和定期重锁流程。

对新项目,可以直接把 pyproject.tomlpylock.toml 作为依赖管理入口。对已有项目,更稳妥的做法是让新旧流程并行一段时间,等 CI、部署和安全工具全部通过验证后,再让 requirements.txt 退出主流程。


相关推荐