PEP 527 – 移除 PyPI 上未(充分)使用的文件类型/扩展名
- 作者:
- Donald Stufft <donald at stufft.io>
- BDFL 委托:
- Alyssa Coghlan <ncoghlan at gmail.com>
- 讨论至:
- Distutils-SIG 邮件列表
- 状态:
- 最终版
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建日期:
- 2016年8月23日
- 发布历史:
- 2016年8月23日
- 决议:
- Distutils-SIG 消息
摘要
本 PEP 建议弃用并最终移除对上传某些未用或未充分使用的文件类型和扩展名到 PyPI 的支持。特别是,它建议禁止进一步上传 bdist_dumb、bdist_rpm、bdist_dmg、bdist_msi 和 bdist_wininst 类型的文件,从而使 PyPI 仅接受 sdist、bdist_wheel 和 bdist_egg 文件类型的新上传。
此外,本 PEP 提议移除对使用 .tar、.tar.bz2、.tar.xz、.tar.Z、.tgz、.tbz 以及除 .tar.gz 和 .zip 之外任何其他扩展名的源发行包 (sdist) 新上传的支持。
最后,本 PEP 还提议限制 PyPI 上项目每个单独版本允许的源发行包上传数量为一份,而不是每个允许的扩展名一份。
基本原理
文件格式
目前 PyPI 支持以下文件类型:
sdist (源发行包)bdist_wheel (wheel 二进制发行包)bdist_egg (egg 二进制发行包)bdist_wininst (Windows 安装器二进制发行包)bdist_msi (Windows MSI 二进制发行包)bdist_dmg (macOS DMG 二进制发行包)bdist_rpmbdist_dumb
然而,这些不同类型的文件在生态系统中的有用性或普遍使用量各不相同。继续支持它们增加了 PyPI 以及工具作者的维护负担,并在 PyPI 本身以及任何 PyPI 镜像上产生了带宽和磁盘空间成本。
Python 包管理是一个多层次的生态系统,其中 PyPI 主要适合并用于直接从各自项目所有者分发与虚拟环境兼容的包。这些包要么由最终用户直接使用,要么由下游分销商使用,这些分销商获取这些包并将其转换为各自的系统级包(例如 RPM、deb、MSI 等)。
虽然 PyPI 本身只直接处理这些特定于 Python 但平台无关的包,但我们鼓励社区驱动和商业化的将这些包转换为特定目标环境的下游格式,例如:
- conda 跨平台数据分析生态系统 (conda-forge)
- 基于 deb 的 Linux 生态系统 (Debian, Ubuntu 等)
- 基于 RPM 的 Linux 生态系统 (Fedora, openSuSE, Mageia 等)
- 适用于 Mac OS X 的 homebrew, MacPorts 和 fink 生态系统
- Windows 包管理生态系统 (NuGet, Chocolatey 等)
- 第三方创建 Windows MSI 和安装器 (例如 Christoph Gohlke 在 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 的工作)
- 其他商业再分发格式 (ActiveState 的 PyPM, Enthought Canopy 等)
- 其他开源社区再分发格式 (Nix, Gentoo, Arch, *BSD 等)
本 PEP 认为,通过让 PyPI 专注于平台无关的格式,可以最好地支持整个生态系统,这样志愿者的有限时间可以得到最佳利用,而不是分散到多个平台。此外,本 PEP 认为,最能为特定平台提供良好集成包的人是专注于该平台的人,而不是专注于所有可能平台的人。
bdist_dumb
顾名思义,bdist_dumb 不是一个非常复杂的格式,但它过于简单,以至于在实际使用中毫无价值。
例如,如果您在 macOS 上使用 pyenv 之类的工具,并且正在使用 Python 3.5 构建一个库,那么 bdist_dumb 将生成一个名为 exampleproject-1.0.macosx-10.11-x86_64.tar.gz 的 .tar.gz 文件。一开始,这个文件名就很难与 sdist 区分开来,因为它们都使用相同的文件扩展名(而且在旧版 PEP 440 之前,1.0-macosx-10.11-x86_64 是一个有效但相当愚蠢的版本号)。然而,一旦您打开创建的 .tar.gz,您会发现里面没有可用于依赖发现等的元数据,事实上,它只是一个包含硬编码路径的 tarball,这些路径指向创建 bdist_dumb 的计算机上文件本应安装的位置。回到我们的 macOS 上的 pyenv 示例,这意味着如果我创建它,它将包含如下文件:
Users/dstufft/.pyenv/versions/3.5.2/lib/python3.5/site-packages/example.py
bdist_rpm
PyPI 上的 bdist_rpm 格式允许人们上传 .rpm 文件供最终用户手动下载和手动安装。然而,rpm 的常见用法是配合专门设计的仓库,该仓库允许自动安装依赖项、升级等,而 PyPI 不提供这些功能。因此,它是一种在 PyPI 上很少使用的文件类型,只有约 460 个此类文件上传到 PyPI(总共 662,544 个文件)。
此外,像 COPR 这样的服务提供了比我们在 PyPI 上可能获得的更好的发布和使用 RPM 文件的机制。
bdist_dmg, bdist_msi, 和 bdist_wininst
bdist_dmg、bdist_msi 和 bdist_wininst 格式类似,它们是特定于操作系统的安装程序,只将库安装到环境中,并非为面向用户的实际应用程序安装而设计(后者需要捆绑 Python 解释器等)。
在这三者中,bdist_dmg 和 bdist_msi 的使用率非常低,仅约 500 个 bdist_msi 文件和约 50 个 bdist_dmg 文件上传到 PyPI。bdist_wininst 格式的使用率较高,约有 14,000 个文件曾上传到 PyPI。
很容易看出 bdist_dmg 和 bdist_msi 的低使用率,并得出移除它们的影响会很小的结论,然而 bdist_wininst 的使用率高出几个数量级。但这有些误导,因为尽管有更多人上传这些文件,但这些上传文件的实际使用率却相当低。查看过去 30 天的数据,我们可以看到 PyPI 上 bdist_wininst 文件下载量的 90% 是由镜像基础设施生成的,而 7% 是由 setuptools 生成的(目前可以通过 bdist_egg 文件更好地覆盖)。
鉴于上传的 bdist_dmg 和 bdist_msi 文件数量很少,并且 bdist_wininst 主要存在是为了通过镜像基础设施消耗带宽和磁盘空间,或者可以轻松地用 bdist_egg 替换,本 PEP 提议将这三种格式纳入不允许的列表。
文件扩展名
目前 sdist 支持多种文件扩展名,如 .tar.gz、.tar、.tar.bz2、.tar.xz、.zip、.tar.Z、.tgz 和 .tbz。然而,在这些扩展名中,只有 .tar.gz(目前有 444,338 个 sdist)、.zip(目前有 58,774 个 sdist)和 .tar.bz2(目前有 3,265 个 sdist)的使用率高于可忽略的程度。
接受多种格式要求 PyPI 内部和外部的工具处理所有可能使用的各种扩展名(即使目前没有人使用它们)。这不仅影响 PyPI,而且对整个生态系统产生连锁反应。此外,不同的格式对 Python 链接的可选 C 库有不同的要求,并且对它们支持的 Python 版本也有不同的要求。此外,多种格式还会造成一种奇怪的情况,即一个特定项目/版本可能存在两个 sdist 文件,内容略有不同。
很容易主张应禁止 .tar.gz、.zip 和 .tar.bz2 之外的所有文件。在 PyPI 存在的约 15 年里,除了极少数人之外,没有人积极上传这些其他类型的文件,因此它们显然没有特别有用。此外,虽然 .tar.xz 由于 LZMA 实现的更好压缩率,理论上比其他 .tar.* 格式更好,但它仅在 Python 3.3+ 中可用,并且对 lzma C 库有可选依赖。
看看我们目前使用的三个扩展名,也很容易得出 .tar.bz2 也可以禁止的结论。它上传的文件数量相当少,并且需要额外的可选 C 库来处理 bzip2 压缩。
最后,我们来看 .tar.gz 和 .zip。从纯粹的数量来看,.tar.gz 显然是上传量最大的格式,总上传量为 444,338,而 .zip 为 58,774。在 POSIX 操作系统上,.tar.gz 也是所有当前发布的 Python 和 setuptools 版本的默认生成格式。此外,这两种文件类型都使用相同的 C 库 (zlib),该库也是 bdist_wheel 和 bdist_egg 所必需的。在 .tar.gz 和 .zip 之间做决定时,有两个复杂之处:虽然在 POSIX 操作系统上 .tar.gz 是默认值,但在 Windows 上 .zip 是默认值,并且 bdist_wheel 格式也使用 zip。
本 PEP 提议我们允许源发行包使用 .tar.gz 或 .zip,而不是试图标准化为其中之一。
限制每个版本源发行包的数量
PyPI 上的源发行包 (sdist) 应该是特定软件版本的单一真理来源。然而,目前 PyPI 允许您为它允许的每个源发行包文件扩展名上传一个源发行包。目前这允许一个项目有大约 10 种不同的源发行包,但即使有本 PEP,它也允许一个版本有两个不同的真理来源。拥有多个源发行包通常会导致奇怪的 bug,这些 bug 只会根据用户使用的源发行包而显现出来。
为了解决这个问题,本 PEP 提议每个项目的每个版本只允许一个源发行包。
移除流程
本 PEP 不提议从 PyPI 中移除任何现有文件,仅禁止上传新文件。此限制将按项目分阶段实施,以允许项目在适用时调整以适应新限制。
首先,任何现有项目将被标记为允许上传旧式文件类型,而任何没有该标记的项目(即新项目)将无法上传除带有 .tar.gz 或 .zip 扩展名的 sdist、bdist_wheel 和 bdist_egg 之外的任何文件。然后,任何从未上传过需要旧式文件类型标记的文件的现有项目都将移除该标记,使其也受新限制的约束。最后,将向所有仍具有旧式标记的项目的维护者发送一封电子邮件,告知他们即将到来的上传新限制,并告诉他们这些限制将在 1 个月后开始应用于他们项目未来的上传。最后,1 个月后,所有项目都将移除旧式文件类型标记,并且 PyPI 将停止支持上传这些类型的文件。
这项计划应该将干扰降到最低,因为它不移除任何现有文件,并且它阻止上传的文件类型要么不是特别有用(或被使用)的文件类型,要么它们可以通过对其流程进行微小更改来继续上传类似类型的文件。
版权
本文档已置于公共领域。
来源: https://github.com/python/peps/blob/main/peps/pep-0527.rst
最后修改: 2025-02-01 08:59:27 GMT