You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Poetry构建冻结所有依赖的Python Wheel包?

使用Poetry构建并生成冻结所有依赖的Python Wheel包方案

核心需求

我需要用Poetry构建Python应用包,并完全冻结所有依赖版本,生成类似Home Assistant那样的受控Wheel包——确保安装时的依赖版本和应用构建验证时完全一致,避免因外部依赖未遵循SemVer、版本冲突(如sphinx与flake8的import-resource版本矛盾)导致应用崩溃、功能异常的问题。

注:这里讨论的是终端应用,而非供其他项目依赖的可共享库(后者在PyPI发布时声明版本范围是合理的)。

当前方法的局限

目前我通过poetry export生成prod-requirements.txt,再用pip install -c prod-requirements.txt来约束版本,但这种方式无法在pipx中生效——而我习惯用pipx为每个应用创建独立虚拟环境,同时希望开发依赖也能隔离(比如sphinx和flake8各用独立环境)。

可行的组合式实现方案

以下是无需等待Poetry官方支持,可自行实现的步骤:

步骤1:生成精确锁定的依赖清单

首先确保Poetry已锁定所有依赖版本:

poetry lock --no-update

然后导出生产环境的精确依赖到requirements.txt:

poetry export --without-hashes --format=requirements.txt --output=prod-requirements.txt

(如果需要包含哈希值增强安全性,去掉--without-hashes参数)

步骤2:构建基础Wheel包

用Poetry构建应用的基础Wheel包:

poetry build --format=wheel

构建好的Wheel包会出现在dist/目录下。

步骤3:修改Wheel包嵌入冻结依赖清单

Wheel本质是zip文件,可通过手动或脚本方式将prod-requirements.txt嵌入并修改元数据:

  1. 将Wheel包重命名为.zip后缀,解压到临时目录
  2. 将prod-requirements.txt放入解压后的根目录
  3. 编辑RECORD文件,添加prod-requirements.txt,,条目
  4. 修改METADATA文件,在Requires-Dist字段后添加:
    Requires-Dist: -r prod-requirements.txt
    
  5. 重新打包为Wheel格式(改回.whl后缀,保持原命名规范)

步骤4:适配pipx的安装脚本

创建自定义安装脚本,自动提取嵌入的依赖清单并传入pipx:

#!/bin/bash
WHEEL_FILE="$1"
# 提取依赖清单到临时文件
unzip -p "$WHEEL_FILE" prod-requirements.txt > /tmp/temp-constraints.txt
# 用pipx安装并指定约束
pipx install "$WHEEL_FILE" --pip-args "-c /tmp/temp-constraints.txt"
# 清理临时文件
rm /tmp/temp-constraints.txt

步骤5:开发依赖的隔离方案

在pyproject.toml中定义开发依赖组:

[tool.poetry.group.docs.dependencies]
sphinx = "^7.0.0"

[tool.poetry.group.lint.dependencies]
flake8 = "^6.0.0"

然后为每个组创建独立虚拟环境:

# 为文档构建创建独立环境
poetry install --with docs --no-root
# 为代码检查创建独立环境
poetry install --with lint --no-root

理想工具设想

我希望有一个工具可以直接接收原始Wheel包和冻结的requirements.txt,自动完成嵌入依赖清单、修改元数据的操作,生成开箱即用的冻结依赖Wheel包。


内容的提问来源于stack exchange,提问作者Gaetan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:54:13