首页
/ Poetry 版本演进与变更历史解析:从 0.12 到 2.4.1 的升级路线、破坏性变更与关键修复

Poetry 版本演进与变更历史解析:从 0.12 到 2.4.1 的升级路线、破坏性变更与关键修复

2026-09-05 18:35:48作者:柯茵沙

本篇基于 Poetry 仓库中的 CHANGELOG.md 撰写,带你系统读懂这份跨越 2019 年至 2026 年、覆盖 100 余个版本记录的变更日志:你将掌握每个大版本引入的核心能力与破坏性变更、如何判断哪些升级是"必须关注"的、以及新版本配置项(如 solver.min-release-ageinstaller.re-resolve)在源码中的真实实现位置,从而在升级或排障时快速定位版本行为差异。

变更日志的组织方式

CHANGELOG.md 采用 "Keep a Changelog" 风格组织,每个版本条目形如 ## [x.y.z] - YYYY-MM-DD,其下按固定小节分类:

  • Added:新增能力,如新命令、新配置项;
  • Changed:行为变更,包括依赖版本区间调整、默认值变化;
  • Fixed:缺陷修复;
  • Docs:文档改进;
  • poetry-core:随同版本发布的配套包 poetry-core 的独立变更记录(如 poetry-core 2.4.0 更新了内嵌的 packaging 到 26.2)。

值得注意的版本语义约定:

  1. 预发布版本带后缀。日志中可见 1.1.0rc11.2.0b11.2.0a1 这类 release candidate / beta / alpha 标记,且预发布线与稳定线(1.0.x、1.1.x)并行记录,说明 Poetry 在 1.x 时代就采用"稳定版打补丁 + 下一主线功能累积"的双轨发布节奏。
  2. 重大变更用加粗标记。例如 2.3.0 中的 "Drop support for Python 3.9"、2.0.0 中的 "Change the default behavior of poetry lock to --no-update"。加粗条目即升级时必须阅读项。
  3. 每条记录附 PR 编号(如 #10824),便于溯源到具体提交与讨论(此处不做外链,读者可按编号检索上游仓库)。

当前仓库 pyproject.toml 中声明的版本为 2.5.0.dev0requires-python = ">=3.10,<4.0",说明本仓库快照对应 2.4.1 发布(2026-05-09)之后的 2.5 开发线,日志本身止于 2.4.1。

版本演进主线时间轴

按日志中各版本条目整理的关键节点如下(日期均取自 CHANGELOG.md):

0.x 到 1.0:奠定依赖管理与环境模型

  • 2019-07-03,0.12.17:日志中最早的条目,此阶段集中在修复依赖解析(循环依赖)、Windows 编码、.venv 处理等基础问题。
  • 2019-12-12,1.0.0:首个稳定大版本。新增 export 命令、env info / env use / env list / env remove 环境子命令、完整的环境标记(markers)支持、URL 依赖、PyPI API token 发布、Conda 环境检测等;同时变更了 lock 文件格式、将 cache:clear 等旧命名命令改为空格风格(cache clear)、poetry run 改用 os.execvp()。这是理解 Poetry 命令命名风格的起点。

1.x 时代:稳定迭代

  • 1.1.0(2020-10-01)→ 1.8.5(2024-12-06):日志中该区间记录了约 30 个版本,以 Fixed 与 Changed 为主,覆盖 lock 幂等性、markers 求值、路径依赖识别等长尾问题。1.8.0(2024-02-25)是该主线最后一个功能版本,1.8.1–1.8.5 均为修复版本。

2.0.0(2025-01-05):最大的一次破坏性升级

这是整份日志中信息密度最高的条目,可归纳为四类:

  1. 拥抱 PEP 标准:支持 pyproject.toml 的 PEP 621 project 表,并相应弃用 tool.poetry 中的重复字段;poetry init 新建项目时 Python 约束默认用 >= 而非 ^,且 build-system 限制在当前 poetry-core 主版本内。
  2. 插件体系落地:新增"项目所需插件(project plugins)"支持——插件可随项目声明并在缺失时自动安装(对应源码 src/poetry/plugins/src/poetry/puzzle/provider.py 周边的加载逻辑);同时 poetry-plugin-export 不再是默认依赖,poetry export 需要显式安装插件,poetry shell 外移到 poetry-plugin-shell
  3. lock 语义变化poetry lock 默认行为改为 --no-update(只补全、不升级),旧行为需显式 --regenerate;lock 文件现在会记录解析出的 markers 与 groups,并提供 installer.re-resolve(当时默认 true)允许跳过重新解析直接安装;不再读取 1.0 之前生成的 lock 文件。
  4. 命令与配置重构:新增 poetry sync(替代 poetry install --sync,后者弃用)、poetry env activate(替代 poetry shell)、poetry add --markerspoetry config --migrate--project 选项;--directory/-C 从"模拟切换"改为"真正切换目录";poetry add --optional 现在必须指定所属 extra;移除 pip 回退安装路径(installer.modern-installation = false)、移除 virtualenvs.options.no-setuptoolsexperimental.system-git-client 更名为 experimental.system-gitvirtualenvs.prefer-active-python 被反转为 virtualenvs.use-poetry-python放弃 Python 3.8 支持

2.0.1 – 2.1.x(2025 上半年):修复与性能

  • 2.0.1(2025-01-11):修复 poetry sync 未移除多余包、--only 误卸载其他组包等 2.0.0 引入的回归。
  • 2.1.0(2025-02-15)poetry build 变为构建后端无关(build-system agnostic),新增 --config-settings;加入(实验性的)poetry python 命令族管理 Python 安装(对应 src/poetry/console/commands/python/);改用 findpython 发现解释器;poetry new 默认 src 布局。
  • 2.1.1–2.1.4(2025-02-16 ~ 2025-08-05):围绕 marker 锁定正确性、lock 确定性、virtualenv 版本区间等持续修复;2.1.2 还专门优化了 poetry lock 性能。

2.2.0(2025-09-14):依赖组成为一等公民

  • 支持 PEP 735 依赖组并支持组嵌套(include-group),组名归一化;
  • 支持 PEP 639 许可证规范;
  • poetry show 增加 --format json
  • 官方支持 Python 3.14;
  • installer.no-binary / only-binary 中显式包名优先于 :all:

2.3.0(2026-01-18):又一次默认值翻转与能力扩展

  • 放弃 Python 3.9 支持
  • installer.re-resolve 默认值由 true 改为 false(即默认信任 lock 中记录的解析结果、不再重新解析);
  • PEP 735 依赖组被纳入 lock 文件哈希计算;
  • 支持通过 poetry-plugin-export 导出 pylock.toml
  • 支持为依赖声明构建约束(build constraints)、支持版本由构建后端动态决定的产物发布;
  • poetry cache clear 可省略缓存名以清空全部缓存;
  • legacy 仓库优先走 JSON API 而非 HTML 页面。

2.3.3 – 2.3.4(2026-03-29 / 2026-04-12):安全修复窗口

这两个版本值得单独强调,因为涉及供应链安全:

  • 2.3.3修复 wheel 安装器中的路径穿越漏洞(恶意 wheel 可写出安装目录之外,见 src/poetry/installation/wheel_installer.py),并顺带修复 HTTP Basic 认证凭据在长 token 下损坏、空 VIRTUAL_ENV/CONDA_PREFIX 误判等;
  • 2.3.4:修复 sdist 解压在 Python 3.10.0–3.10.12 与 3.11.0–3.11.4 上的路径穿越漏洞,并修复 2.3.3 引入的 wheel 安装性能回退。

同期 2.3.3 还修复了 poetry init / poetry new 创建已弃用的 project.license 格式的问题(呼应 2.2.0 引入的 PEP 639)。

2.4.0 – 2.4.1(2026-05-03 / 2026-05-09):发布年龄过滤

这是日志中最新的两个版本,其核心新增是三个 solver 配置项:

  • solver.min-release-age:要求发布版本"至少存在 N 天"后才参与依赖解析,用于过滤刚发布、可能未经充分检验的构件;
  • solver.min-release-age-exclude:按包名排除,被排除的包始终参与解析;
  • solver.min-release-age-exclude-source:按来源(仓库名或 URL)整体排除年龄过滤。

其余变更包括:poetry update 传入非依赖包名时由静默忽略改为报错;legacy 仓库发布 URL 自动补尾斜杠;要求 installer>=1.0.0;以及一批修复——lock 文件 marker 顺序确定性、poetry publish --build 忽略失败构建上传过期产物、lazy-wheel 取元数据后未关闭 zip / 缓存数据损坏、大 wheel 计算哈希内存溢出等。2.4.1 则修复了 poetry update <package><package> 为传递依赖时失败的问题(PR #10885),并重新放行 installer==0.7.0

2.5.0.dev0:当前开发线

pyproject.toml 可见当前开发版本依赖了 pbs-installerfindpython (>=0.6.2,<0.9.0)tomlkit 等,poetry-core 以 git 依赖方式引入,说明仓库处于 2.5 开发早期。

破坏性变更清单:升级前必读

汇总日志中以加粗标记或语义上会改变用户行为的条目,供升级时对照检查:

版本 变更 影响面
1.0.0 lock 文件格式变更;cache:clear 等命令改名 旧 lock 需重新生成
2.0.0 poetry lock 默认 --no-update,旧行为需 --regenerate 升级流程脚本
2.0.0 poetry export / poetry shell 移出核心,需安装对应插件 CI 导出依赖场景
2.0.0 poetry add --optional 必须指定 extra 添加可选依赖的用法
2.0.0 --directory/-C 真正切换目录 依赖相对路径解析的插件/脚本
2.0.0 / 2.3.0 放弃 Python 3.8 / 3.9 可运行的解释器范围
2.0.0 移除 pip 回退安装路径、不再默认装 setuptools 含 C 扩展的特殊构建环境
2.0.0 experimental.system-git-clientsystem-git-clientvirtualenvs.prefer-active-pythonvirtualenvs.use-poetry-python(语义反转) 存量 poetry.toml 配置,可用 poetry config --migrate 迁移
2.3.0 installer.re-resolve 默认 truefalse 默认不再重新解析,lock 记录的 markers/groups 更权威

其中 poetry config --migrate(2.0.0 引入)专门用于迁移过期配置项,是升级 2.0 后的推荐第一步。

源码印证:新配置项如何落地

solver.min-release-age 的实现

2.4.0 引入的三个配置项在源码中的落点:

  1. 默认值定义在 src/poetry/config/config.pyConfig.default_config 中:

    "solver": {
        "lazy-wheel": True,
        "min-release-age": 0,
        "min-release-age-exclude": None,
        "min-release-age-exclude-source": None,
    },
    

    默认 min-release-age0,即不启用过滤,与日志"新增配置"的定位一致——行为向后兼容。

  2. 过滤逻辑实现在 src/poetry/repositories/http_repository.pyHTTPRepository 初始化时读取 solver.min-release-age,若当前仓库的包名或 URL 命中 exclude / exclude-source 名单则整体禁用过滤;否则以 datetime.now() - timedelta(days=min_release_age) 计算截止时间,版本列表构建阶段按 upload_time 过滤(src/poetry/repositories/repository.py 附近提供忽略版本的日志)。注意过滤依赖 PyPI JSON API 的 upload_time 字段,因此只作用于 HTTP/PyPI 类仓库。

  3. 命令行校验src/poetry/console/commands/config.pysolver.min-release-age 必须为非负整数,两个 exclude 项为逗号分隔列表。

  4. 用户文档见 docs/configuration.md,给出配置示例:

    poetry config solver.min-release-age-exclude "my-package,other-package"
    poetry config solver.min-release-age-exclude-source "private-repo,https://example.com/simple/"
    

    其中 exclude-source 同时支持仓库名与仓库 URL 两种写法。

installer.re-resolve 的默认值轨迹

日志记录该选项 2.0.0 引入(默认 true)、2.3.0 改为默认 false。当前代码 src/poetry/config/config.pyinstaller 默认值块印证了 2.3.0 之后的状态:

"installer": {
    "re-resolve": False,
    "parallel": True,
    "max-workers": None,
    "no-binary": None,
    "only-binary": None,
    "build-config-settings": {},
},

这意味着从 2.3.0 起,poetry install 默认直接采用 lock 中记录的结果;如果你的团队依赖"安装时自动重解析",需显式 poetry config installer.re-resolve true

使用变更日志的三条实操建议

  1. 先看加粗条目再看 Fixed:加粗项(如各版本 "Drop support for Python 3.x"、"Change the default of …")决定兼容性,Fixed 决定你踩过的坑是否已修(例如 2.3.3 的路径穿越漏洞应视为强制升级点)。
  2. poetry-core 小节与主版本绑定阅读:Poetry 的元数据解析、marker 计算、PEP 621/735 字段处理大多在 poetry-core 中完成,日志中大量 "poetry-core (…)" 小节解释了 Poetry 主版本的解析行为变化(如 2.1.2 的 marker 交集/并集确定性修复、2.2.0 的版本归一化)。排障依赖解析异常时应一并查看。
  3. 对照 docs/configuration.mddocs/cli.md 验证:CHANGELOG 记录"何时变",docs 记录"现在是什么样"。例如 solver.min-release-age 的完整取值与示例在 docs/configuration.md 中,命令选项细节在 docs/cli.md

版本选型参考

结合日志与仓库现状,可归纳的选型原则(以本仓库快照为准):

  • 新项目直接使用 2.4.x+:可获得 solver.min-release-age 年龄过滤、确定性的 lock 输出、2.3.4 之后的安全修复;注意 2.3.0 起要求 Python 3.10+(仓库 requires-python = ">=3.10,<4.0")。
  • 仍停留在 1.8.x 的团队:升级路径需先处理 2.0.0 的 lock --no-update 默认值、export/shell 插件化、add --optional 新接口三类破坏性变更,再用 poetry config --migrate 迁移配置。
  • 安全敏感场景:不应运行早于 2.3.3 的版本(wheel 路径穿越)与早于 2.3.4 的版本(sdist 路径穿越)。

CHANGELOG 完整内容见仓库根目录的 CHANGELOG.md,从 2.4.1 一路追溯到 0.12.17 的 2890 行记录,是理解 Poetry 任一版本行为差异的第一手资料。

登录后查看全文
热门项目推荐
相关项目推荐