PEP 643 – 包源发行版元数据
- 作者:
- Paul Moore <p.f.moore at gmail.com>
- BDFL 代表:
- Paul Ganssle <paul at ganssle.io>
- 讨论邮件列表:
- Discourse 帖子
- 状态:
- 最终
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建:
- 2020-10-24
- 发布历史:
- 2020-10-24, 2020-11-01, 2020-11-02, 2020-11-14
- 决议:
- Discourse 消息
摘要
Python 包元数据以标准格式存储在发行版文件中,该格式在 核心元数据规范 中定义。但是,对于源发行版,虽然数据格式已定义,但传统上源发行版中记录的数据存在很多不一致性。请参阅 此处 以了解此问题的讨论。
结果,元数据使用者无法依赖源发行版中提供的数据,并且需要使用(代价高昂的)PEP 517 构建机制来提取元数据。
此 PEP 定义了一个标准,允许构建后端在源发行版中可靠地存储包元数据,同时仍然保留处理必须在构建时计算的元数据字段的必要灵活性。
动机
当前在源发行版中存储元数据的方式存在许多问题
- 存储元数据的方法细节虽然已标准化,但并不容易找到。
- 规范需要旧的元数据版本,并且尚未根据核心元数据规范的更改进行更新。
- 规范中没有办法区分“此字段已省略,因为其值在构建时才会知道”和“此字段没有值”。
- 核心元数据规范允许大多数字段是可选的,这意味着先前的问题几乎影响每个元数据字段。
此 PEP 提出更新元数据规范,以允许记录预期“稍后填充”的字段,并更新源发行版规范以阐明后端应使用该规范版本(或更高版本)记录 sdist 元数据。
基本原理
此 PEP 允许项目将源发行版元数据值定义为“动态”。在此上下文中,将字段称为“动态”表示在生成源发行版时该值尚未固定。动态值将在生成 wheel 时由构建后端提供,并且可能取决于构建环境的详细信息。
PEP 621 有一个类似的概念,“动态”值将“稍后填充”,因此我们通过类比选择在此处使用相同的术语。
规范
此 PEP 定义了源发行版中指定的元数据值与其从中构建的 wheel 中的对应值之间的关系。它要求构建后端明确标记任何不会简单地从 sdist 未经更改地复制到 wheel 的字段。
此外,此 PEP 使 PyPA 规范 文档成为源发行版格式规范的规范位置(收集 PEP 517 和此 PEP 中的信息)。
一个新的字段,Dynamic
,将被添加到 核心元数据规范 中。此字段将是多用途的,并且允许包含另一个核心元数据字段的名称。
在源发行版的元数据中找到时,以下规则适用
- 如果一个字段未标记为
Dynamic
,则从 sdist 构建的任何 wheel 中该字段的值必须与 sdist 中的值匹配。如果该字段不在 sdist 中,并且未标记为Dynamic
,则它必须不出现在 wheel 中。 - 如果一个字段被标记为
Dynamic
,则它可能包含从 sdist 构建的任何 wheel 中的任何有效值(包括根本不存在)。 - 后端必须不要将字段标记为
Dynamic
,如果他们可以确定它是从在构建时不会更改的数据生成的。
后端可以记录他们为标记为 Dynamic
的字段计算的值在源发行版中。但是,使用者必须不要将此值视为规范,但可以将其用作有关 wheel 中最终值可能是什么的提示。
在源发行版之外的任何上下文中,如果一个字段被标记为 Dynamic
,则表示该值是在 wheel 构建时生成的,可能与 sdist 中的值(或项目的其他构建)不匹配。但是,后端不需要记录此信息,并且使用者必须不要假设 Dynamic
标记的缺乏有任何意义,除了在源发行版中。
字段 Name
和 Version
必须不要标记为 Dynamic
。
由于它添加了一个新的元数据字段,因此此 PEP 将核心元数据格式更新为版本 2.2。
源发行版应该使用创建时可用的最新版本的核心元数据规范。
强烈建议构建后端仅在绝对必要时才将字段标记为 Dynamic
,并鼓励项目避免需要使用 Dynamic
的后端功能。项目应该更喜欢对静态值使用环境标记以适应安装位置的详细信息。
向后兼容性
由于此提案增加了核心元数据版本,因此它与现有源发行版兼容,后者将使用旧的元数据版本。工具可以通过检查元数据版本来确定源发行版是否符合此 PEP。
安全影响
由于此规范纯粹用于存储旨在公开提供的数据,因此没有安全影响。
如何教授
这是项目元数据的存储格式,因此通常不会对最终用户可见。因此,无需教用户如何使用此格式。希望引用元数据的开发人员可以在 PyPA 规范 中找到详细信息。
被拒绝的想法
- 而不是将字段标记为
Dynamic
,应该假设字段是动态的,除非明确标记为Static
。这在逻辑上等同于当前提案,但它意味着字段是动态的是常态。在存在已知为静态的元数据的情况下,打包工具可以更高效,因此 PEP 选择使动态字段成为例外,并要求后端“选择加入”使字段动态。
此外,如果动态是默认值,那么将来,随着越来越多的元数据变得静态,元数据文件将包含越来越多的
Static
声明。 - 而不是使用
Dynamic
字段,添加一个特殊值来指示字段“尚未定义”。同样,这在逻辑上等同于当前提案。它使“成为动态”成为明确的选择,但需要一个特殊值。由于某些字段可以包含任意文本,因此选择这样的值有点尴尬(尽管在实践中可能不是问题)。这种方法似乎没有足够的优势来使其值得使用而不是建议的机制。
- 对
Requires-Python
的特殊处理。PEP 的早期草案需要对
Requires-Python
进行专门讨论,因为此字段缺乏环境标记意味着可能难以要求其为静态。PEP 的最终形式不再需要此功能,因为允许动态的字段白名单的想法已被放弃。 - 将
Dynamic
的使用限制在允许的字段的最小“白名单”中。由于 setuptools 接口的动态特性,这种方法可能难以以向后兼容的方式由 setuptools 实现。相反,该提案现在允许大多数字段是动态的,但鼓励后端避免动态值,除非必要。
未解决的问题
无
版权
此文档放置在公共领域或根据 CC0-1.0-Universal 许可证,以较宽松者为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0643.rst
上次修改时间:2023-09-09 17:39:29 GMT