PEP 685 – 比较可选发行版依赖项的额外名称
- 作者:
- Brett Cannon <brett at python.org>
- PEP-委托人:
- Paul Moore <p.f.moore at gmail.com>
- 讨论地址:
- Discourse 线程
- 状态:
- 已接受
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建:
- 2022-03-08
- 历史记录:
- 2022-03-08
- 决议:
- Discourse 消息
摘要
此 PEP 指定了在执行比较时如何规范化 发行版额外 名称。这可以防止工具无法找到额外名称,或意外匹配到意外名称。
动机
在 Provides-Extra 核心元数据规范中指出,额外的名称“必须是有效的 Python 标识符”。PEP 508 指定,extra
标记的值可以在初始字符之后包含字母、数字或以下任何一个:.
、-
或 _
。没有其他 PyPA 规范 说明如何编写或规范化额外名称以进行比较。由于现有的与打包相关的代码数量庞大,因此重要的是评估社区当前的实践并将其标准化为一种不会破坏大多数现有代码的实践,同时也是工具作者可以同意遵循的实践。
关于没有一致标准的问题是通过 最初的讨论 提出的,该讨论指出,额外名称 adhoc-ssl
在 pip 22 中不被认为等同于名称 adhoc_ssl
。
基本原理
PEP 503 指定了如何规范化发行版名称
re.sub(r"[-_.]+", "-", name).lower()
这会将任何 -
、_
和 .
字符序列合并为单个 -
。例如,---
、.
和 __
都将转换为 -
。这不会生成有效的 Python 标识符,根据核心元数据 2.2 规范中关于额外名称的定义。
Setuptools 60 执行规范化 通过以下方式进行
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 上的轮包集合进行的研究 [pypi-results],考虑到 PyPI 上的所有额外名称,无论有效与否(不仅仅是单个包中的名称),额外名称冲突的风险仅限于 73 个实例,而仅查看有效的名称会导致只有 3 个冲突
dev-test
:dev_test
,dev-test
,dev.test
dev-lint
:dev-lint
,dev.lint
,dev_lint
apache-beam
:apache-beam
,apache.beam
通过要求编写核心元数据的工具仅记录规范化的名称,现有无效的额外名称问题应该会随着时间的推移而减少。
安全隐患
对于具有冲突的额外名称的发行版来说,工具最终可能会安装依赖项,这些依赖项在某种程度上会削弱系统的安全性。这仅仅是假设性的,如果真的发生了,这将更多地是指定此类额外名称的发行版的安全问题,而不是拉取这些发行版的发行版。
如何教授
这在日常使用中应该对用户来说是透明的。当用户选择冲突的额外名称时,将由工具来教育/阻止用户。
参考实现
除了上面的代码之外,没有提供参考实现,但预期 打包项目 会在其 packaging.utils
模块中提供一个函数来实现额外名称规范化。它还会适当地实现额外名称比较。最后,如果该项目最终获得了编写元数据的能力,它也会实现此 PEP。
过渡计划
存在这样的风险,即构建工具可能会生成符合版本 2.3 的核心元数据,从而符合此 PEP,但会被一个不知道此 PEP 的工具使用(如果该工具选择尝试读取它不支持的核心元数据版本)。在这种情况下,用户可能会指定一个以前有效的非规范化名称,但现在会失败。
因此,应该优先考虑此 PEP 的使用者,而不是生产者,以便可以通知用户他们正在指定未规范化的额外名称(因此将来可能会出现问题)。
拒绝的方案
使用 setuptools 60 的规范化
最初,此 PEP 提出使用 setuptools 的 safe_extra()
来进行规范化,以尽量减少向后兼容性问题。但是,在检查了 PyPI 上的各种轮包之后,很明显,将所有命名标准化为 PEP 508 和 PEP 503 语义会更容易,并且从长远来看会更好,同时会产生最小的向后兼容性问题。
待解决的问题
N/A
版权
此文档放置在公共领域或根据 CC0-1.0-Universal 许可证,以较宽松的许可为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0685.rst
最后修改时间:2023-09-09 17:39:29 GMT