PEP 685 – 可选分发依赖项的额外名称比较
- 作者:
- Brett Cannon <brett at python.org>
- PEP 代理人:
- Paul Moore <p.f.moore at gmail.com>
- 讨论至:
- Discourse 帖子
- 状态:
- 最终版
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建日期:
- 2022年3月8日
- 发布历史:
- 2022年3月8日
- 决议:
- Discourse 消息
摘要
本 PEP 规定了在执行比较时如何规范化分发额外名称。这可以防止工具无法找到额外名称,或意外地匹配到意想不到的名称。
动机
Provides-Extra 核心元数据规范规定额外名称“必须是有效的 Python 标识符”。PEP 508 规定 extra 标记的值在初始字符之后可以包含字母、数字或任何一个 .、- 或 _。没有其他 PyPA 规范概述额外名称应如何编写或规范化以进行比较。由于存在大量与打包相关的代码,因此评估社区当前的实践并标准化一个不会破坏大多数现有代码,同时工具作者也同意遵循的方法非常重要。
由于缺乏一致的标准,最初的讨论提出了这个问题,指出 pip 22 不认为额外名称 adhoc-ssl 等同于 adhoc_ssl。
基本原理
PEP 503 规定了如何规范化分发名称
re.sub(r"[-_.]+", "-", name).lower()
这会将 -、_ 和 . 字符的任何连续序列缩减为单个 -。例如,--- . 和 __ 都将被转换为单个 -。根据核心元数据 2.2 规范对额外名称的规定,这不会生成有效的 Python 标识符。
re.sub(r'[^A-Za-z0-9-.]+', '_', name).lower()
下划线/_ 的使用与 PEP 503 中连字符/- 的使用不同,并且它还规范化了 PEP 508 允许的字符之外的字符。. 和 - 的连续序列,与 PEP 503 不同,不会被规范化为一个 _,例如 .. 保持不变。需要注意的是,这与该函数的文档字符串不一致,该文档字符串确实指定所有非字母数字字符(包括 - 和 .)都被规范化和折叠。
对于 pip 22,其“额外规范化行为相当复杂和不稳定”[pip-erratic],因此不考虑其使用。
规范
在比较额外名称时,工具必须使用 PEP 503 中概述的语义对要比较的名称进行规范化
re.sub(r"[-_.]+", "-", name).lower()
核心元数据规范将进行更新,以便 Provides-Extra 允许的名称与 PEP 508 为名称指定的名称匹配。这将使额外命名与 Name 字段的命名保持一致。由于这改变了被认为是有效的内容,因此将导致核心元数据版本增加到 2.3。
对于编写核心元数据的工具,它们必须以规范化形式写入额外名称。这适用于 Provides-Extra 字段以及在 Requires-Dist 字段中使用时应用的 额外标记。
生成元数据的工具,如果用户指定了两个或多个额外名称,并且这些名称规范化后相同,则必须引发错误。生成元数据的工具,如果提供了无效的额外名称,则必须根据指定的核心元数据版本适当地引发错误。如果项目的元数据指定了较旧的核心元数据版本,并且该名称在较新的核心元数据版本中无效,则读取该元数据的工具应警告用户。读取到无效额外名称时,工具应警告用户并应忽略该名称以避免歧义。如果需要,工具可以引发错误而不是警告来读取无效名称。
向后兼容性
转向 PEP 503 规范化和 PEP 508 名称接受,允许所有预先存在的有效名称继续有效。
根据对 PyPI 上一系列 wheel 文件的研究[pypi-results],在考虑 PyPI 上所有额外名称(无论是否有效,不限于单个包内)时,额外名称冲突的风险仅限于 73 个实例;而仅考虑有效名称时,冲突仅有 3 个:
dev-test:dev_test,dev-test,dev.testdev-lint:dev-lint,dev.lint营养,dev_lintapache-beam:apache-beam,apache.beam
通过要求编写核心元数据的工具只记录规范化名称,预先存在的无效额外名称问题应随着时间而减少。
安全隐患
对于具有冲突额外名称的分发,工具可能会安装一些依赖项,这些依赖项以某种方式削弱系统的安全性。这只是假设,如果发生这种情况,它可能更多的是指定此类额外名称的分发的安全问题,而不是将它们拉到一起的分发的安全问题。
如何教授此内容
这应该对日常用户是透明的。当用户选择冲突的额外名称时,工具将负责教育/阻止用户。
参考实现
除了上面的代码,没有提供参考实现,但预期是 打包项目 将在其 packaging.utils 模块中提供一个函数来实现额外名称规范化。它还将适当实现额外名称比较。最后,如果项目获得写入元数据的能力,它也将实现此 PEP。
过渡计划
存在这样的风险:构建工具将生成符合版本 2.3 和此 PEP 的核心元数据,但该元数据被不了解此 PEP 的工具(如果该工具选择尝试读取它不直接支持的核心元数据版本)使用。在这种情况下,用户可能会指定一个以前有效但现在失败的非规范化额外名称。
因此,应该优先考虑本 PEP 的消费者而不是生产者,以便可以通知用户他们正在指定未规范化的额外名称(因此将来可能会出现问题)。
被拒绝的想法
使用 setuptools 60 的规范化
最初,本 PEP 提议使用 setuptools 的 safe_extra() 进行规范化,以尽量减少向后兼容性问题。然而,在检查 PyPI 上的各种 wheel 文件后,很明显,将所有命名标准化为 PEP 508 和 PEP 503 语义更容易、长期来看更好,同时引起的向后兼容性问题最小。
未解决的问题
不适用
版权
本文档置于公共领域或 CC0-1.0-Universal 许可证下,以更宽松者为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0685.rst