Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 625 – 源分发的文件名

作者:
Tzu-ping Chung <uranusjr at gmail.com>, Paul Moore <p.f.moore at gmail.com>
PEP 代理人:
Pradyun Gedam <pradyunsg at gmail.com>
讨论至:
Discourse 帖子
状态:
最终版
类型:
标准跟踪
主题:
打包
创建日期:
2020年7月8日
发布历史:
2020年7月8日
决议:
Discourse 消息

目录

重要

本 PEP 是一份历史文档。最新的、规范的规格,源分发文件名,维护在 PyPA 规格页面

×

有关如何提出更改的建议,请参阅PyPA 规范更新流程

摘要

本 PEP 描述了源分发(也称为 *sdist*)的标准命名方案。sdist 与包含 Python 包源代码的任意归档文件不同,可用于向打包工具传达有关分发的信息。

此处指定的标准 sdist 是一个 gzipped tar 文件,具有特殊格式的文件名和常见的 .tar.gz 后缀。本 PEP 不指定 tarball 的内容,因为这已在其他规范中涵盖。

动机

sdist 是一种 Python 包分发,包含 Python 包的“源代码”,并且在安装时需要构建步骤才能转换为 wheel。这种格式通常被认为是 PEP 427 wheel 的未构建对应物,并在打包生态系统的各个部分受到特殊对待。

sdist 的内容在 PEP 517PEP 643 中有规定,但目前 sdist 的文件名未完全指定,这意味着格式的使用者必须下载并处理 sdist 以确认其中包含的分发名称和版本。

安装程序目前依赖启发式方法从文件名推断名称和/或版本,以帮助安装过程。例如,pip 从 PEP 503 索引中解析 sdist 的文件名,以获取分发的项目名称和版本,用于依赖解析目的。但由于缺乏规范,安装程序无法保证推断数据的正确性,并且必须在某个时候通过本地构建分发元数据来验证它。

当用户不希望发生构建过程时,此构建步骤对于特定类别的操作来说很麻烦。pypa/pip#8387 描述了一个示例。命令 pip download --no-deps --no-binary=numpy numpy 预期只下载 numpy 的 sdist,因为我们不需要检查依赖项,并且名称和版本都可以通过检查下载的文件名获得。然而,pip 不能假定下载的归档文件遵循约定,并且必须构建和检查元数据。对于 PEP 518 项目,这意味着运行 PEP 517 中指定的 prepare_metadata_for_build_wheel 钩子,这会产生显著的开销。

基本原理

通过为 sdist 格式创建特殊的命名方案,本 PEP 使工具在只需要文件名中可用的元数据时,无需执行耗时的元数据验证步骤。

本 PEP 还作为当前 sdist 实现所使用的长期文件名约定的正式规范。文件名包含分发名称和版本,以帮助工具识别分发,而无需下载、解压缩文件以及执行昂贵的元数据生成以进行内省,如果他们需要的所有信息都可在文件名中获得。

规范

sdist 的名称应为 {distribution}-{version}.tar.gz

  • distributionPEP 345 中定义的分发名称,并按照 wheel 规范 中的描述进行规范化,例如 'pip', 'flit_core'
  • versionPEP 440 中定义的分发版本,例如 20.2,并根据该 PEP 中的规则进行规范化。

sdist 必须是 pax 格式的 gzipped tar 归档文件,可以使用标准库 tarfile 模块和打开标志 'r:gz' 进行提取。

生成 sdist 文件的代码必须为文件命名,使其符合本规范。PEP 517build_sdist 钩子的规范被扩展,要求遵循此命名约定。

处理 sdist 文件的代码可以通过简单地解析文件名来确定分发名称和版本,并且不需要通过生成或读取 sdist 内容中的元数据来验证该信息。

符合规范的 sdist 文件可以通过存在 .tar.gz 后缀和文件名中存在*单个*连字符来识别。请注意,一些旧文件也可能符合这些标准,但这在实践中预计不会成为问题。有关详细信息,请参阅本文档的“向后兼容性”部分。

向后兼容性

新的文件名方案是 sdist 文件当前非正式命名约定的子集,因此创建或发布符合此标准的文件的工具可以被仅理解旧命名约定的旧工具读取。

使用 sdist 文件名的工具在技术上无法确定文件是使用新标准还是旧版形式。然而,对 PyPI 上文件名的审查确定,37% 的文件明显是旧版(因为它们包含多个或没有连字符),其余文件中,根据本 PEP 进行解析在除了 0.004% 的情况外都给出了正确答案。

目前,处理 sdist 的工具,如果它们要完全正确,应将从文件名中解析出的名称和版本视为暂定的,并通过下载文件和生成实际元数据(或者如果 sdist 符合 PEP 643,则读取它)来验证它们。支持此规范的工具可以将文件名中的名称和版本视为确定的。理论上,如果将旧版文件名假定为符合本 PEP,这可能会带来错误风险,但实际上,发生这种情况的可能性似乎微乎其微。

被拒绝的想法

依赖 sdist 元数据的规范

自本 PEP 首次编写以来,PEP 643 已被接受,定义了可信赖的标准 sdist 元数据格式。这允许静态确定分发元数据(特别是名称和版本)。

然而,这被认为是不够的,因为在许多重要情况下(例如,从包索引中读取文件名),应用程序只能访问文件名,读取元数据可能涉及代价高昂的下载。

使用专用的文件扩展名

本 PEP 的原始版本提出了 {distribution}-{version}.sdist 的文件名。这具有显式性的优点,并且允许将来更改存储格式而无需进一步更改文件命名约定。

然而,新的扩展名存在显著的兼容性问题。索引服务器目前可能不允许未知扩展名,如果我们引入一个新的,尚不清楚如何处理诸如旧版索引尝试镜像托管新样式 sdist 的索引的情况。是否可以只部分镜像,省略项目较新版本的 sdist?此外,生成新格式的构建后端将与只接受旧格式的索引服务器不兼容,并且通常用户无法在构建时请求后端较旧版本,这可能导致无法构建和上传 sdist。

增强当前常见的 sdist 命名方案

在最初讨论中提出了 {distribution}-{version}.sdist.tar.gz 方案。由于与当前可用的安装工具的向后兼容性问题,该方案被放弃。例如,pip 20.1 会将 distribution-1.0.sdist.tar.gz 解析为项目 distribution,版本为 1.0.sdist。这将导致 sdist 被下载,但由于元数据不一致而无法安装。

此提案的主要优点是工具更容易识别新样式命名。但鉴于所有名称中带有一个连字符的 sdist 在旧规则和新规则下以相同方式解析,这并不是一个特别显著的优势。

未解决的问题

sdist 的内容需要包含一个名为 {name}-{version} 的顶级目录。目前对该名称的组件没有要求任何规范化规则。本 PEP 是否应该要求在此处应用与文件名相同的规范化规则?请注意,在实践中,工具很可能会使用相同的代码创建这两个名称,因此即使没有明确要求,规范化也可能会自然发生。


来源:https://github.com/python/peps/blob/main/peps/pep-0625.rst

上次修改:2025-05-06 21:28:00 GMT