PEP 592 – 在简单 API 中添加“Yank”支持
- 作者:
- Donald Stufft <donald at stufft.io>
- BDFL 委托:
- Paul Moore <p.f.moore at gmail.com>
- 讨论至:
- Discourse 帖子
- 状态:
- 最终版
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建日期:
- 2019 年 5 月 7 日
- 决议:
- Discourse 消息
摘要
本 PEP 提议在简单存储库中添加将特定文件下载标记为“已下架”的功能。下架文件允许作者有效地删除文件,同时又不会破坏那些已精确锁定到特定版本的人。
它还将简单存储库 API 的规范来源更改为简单存储库 API 参考文档。
动机
每当项目检测到 PyPI 上的特定版本可能已损坏时,他们通常会希望阻止其他用户无意中继续使用该版本。但是,从存储库中删除现有文件的显而易见的解决方案将破坏那些遵循最佳实践并已锁定到项目特定版本的用户。
这使项目陷入两难境地,新项目可能会下载这个已知损坏的版本,但如果他们采取任何措施来阻止这种情况,他们就会破坏已经在使用该版本的项目。
通过允许“下架”文件,但仍将其提供给明确请求它的用户,这使得项目能够减轻最严重的破坏,同时仍能保持那些已解决或未遇到潜在问题的项目正常运行。
发生这种情况的主要场景之一是停止支持特定版本的 Python。 python-requires 元数据允许以不干扰仍在使用该 Python 的用户的方式停止支持 Python 版本。然而,一个常见的错误是省略或忘记更新该元数据位。当发生此错误时,项目实际上只有三种选择
- 通过某种机制阻止安装该版本(目前,唯一的机制是完全删除该版本)。
- 将正常工作的版本重新发布为更高的版本号,然后将停止支持的版本重新发布为具有正确元数据的更高版本号。
- 什么都不做,并记录使用旧 Python 的人必须手动排除该版本。
通过本 PEP,项目可以选择第一个选项,但其机制不太可能破坏那些目前成功使用该项目的人。
规范
简单存储库中的链接**可以**具有 data-yanked 属性,该属性可以没有值,也可以具有任意字符串作为值。 data-yanked 属性的存在**应该**被解释为表示此特定链接指向的文件已被“下架”,并且通常不应由安装程序选择,除非在特定场景下。
如果存在 data-yanked 属性的值,则它是一个任意字符串,表示文件已被下架的原因。处理简单存储库 API 的工具**可以**将此字符串显示给最终用户。
下架属性一旦设置就不是不可变的,将来可能会被撤销(一旦撤销,也可以重新设置)。因此,API 用户**必须**能够处理已下架文件被“取消下架”(甚至再次下架)的情况。
安装程序
对于用户而言,理想的体验是,一旦文件被下架,当人类正在尝试直接安装已下架文件时,它会像该文件已被删除一样失败。但是,当人类在一段时间前执行此操作,并且现在计算机只是继续机械地遵循原始命令安装现在已下架的文件时,它的行为就像没有被下架一样。
如果可以通过未下架版本满足选择约束,则安装程序**必须**忽略已下架版本,并且即使这意味着根本无法满足请求,**也可以**拒绝使用已下架版本。实现**应该**选择遵循上述意图精神的策略,并阻止对已下架版本/文件的“新”依赖。
这意味着什么取决于具体的安装程序,以决定如何最好地适应其安装程序的整体使用。但是,有两种建议的方法
- 已下架文件总是被忽略,除非它们是唯一与使用
==(不带任何使其成为范围的修饰符,例如.*)或===锁定到精确版本的版本说明符匹配的文件。匹配此版本说明符应该像 PEP 440 中那样处理,例如局部版本、零填充等。 - 已下架文件总是被忽略,除非它们是唯一与锁定文件(例如
Pipfile.lock或poetry.lock)指定要安装的文件匹配的文件。在这种情况下,在从某个输入文件或命令创建或更新锁定文件时,**不应**使用已下架文件。
无论安装程序选择何种特定策略来决定何时安装已下架文件,安装程序**应该**在决定安装已下架文件时发出警告。该警告**可以**利用 data-yanked 属性的值(如果它有值)来向用户提供关于该文件为何被下架的更具体反馈。
镜像
镜像通常可以按以下两种方式处理已下架文件
- 它们可以选择从其简单存储库 API 中完全省略它们,提供一个只显示“活动”的未下架文件的存储库视图。
- 它们可以选择包含已下架文件,并同时镜像
data-yanked属性。
镜像**不得**在未同时镜像其 data-yanked 属性的情况下镜像已下架文件。
被拒绝的想法
简单存储库 API 以前有一个未文档化的版本,具有特定版本页面,例如 /simple/<project>/<version>/。如果我们要添加回这些页面,已下架文件只能出现在这些页面上,而不能出现在不带版本的页面上。然而,这将大大降低简单 API 的可缓存性,并直接影响我们扩展它以处理所有传入流量的能力。
本 PEP 的先前迭代中,data-yanked 属性作为布尔值。但是,后来决定允许使用字符串,这既简化了实现,又提供了额外的通用功能,允许项目提供一种机制来指示他们下架版本的原因。
另一个建议是,在任意字符串中保留一些语法,以便将来如果需要,我们可以发展标准。然而,考虑到我们将来可以添加额外的属性,这个想法已被拒绝,转而倾向于如果出现需要,则使用额外的属性。
Warehouse/PyPI 实现注意事项
虽然本 PEP 在文件级别实现下架,但这主要是由于简单存储库 API 的形式,而不是本 PEP 做出的具体决定。
在 Warehouse 中,用户体验将以“下架”或“取消下架”整个版本的方式实现,而不是作为对单个文件的操作,然后通过 API 将其公开为单个文件被下架。
其他存储库实现可能会选择以不同的方式公开此功能,或者根本不公开。
日志处理
每当版本被下架时,都会使用以下字符串模式之一在日志中记录条目
下架 版本取消下架 版本
在这两种情况下,标准日志结构都会指示哪个项目的哪个版本已被下架或取消下架。
版权
本文档已置于公共领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0592.rst
最后修改时间:2025-02-01 08:55:40 GMT