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

Python 增强提案

PEP 610 – 记录已安装发行版的直接 URL 来源

作者:
Stéphane Bidoul <stephane.bidoul at gmail.com>,Chris Jerdonek <chris.jerdonek at gmail.com>
发起人:
Alyssa Coghlan <ncoghlan at gmail.com>
BDFL 委托
Pradyun Gedam <pradyunsg at gmail.com>
讨论至:
Discourse 帖子
状态:
最终版
类型:
标准跟踪
主题:
打包
创建日期:
2019 年 4 月 21 日
发布历史:

决议:
Discourse 消息

目录

重要

本 PEP 是一份历史文档。最新、权威的规范《记录已安装发行版的直接 URL 来源》维护在 PyPA 规范页面上。

×

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

摘要

根据 PEP 440,发行版可以通过名称和版本,或直接 URL 引用进行识别(参见 PEP440 直接引用)。安装后,名称和版本会记录在项目元数据中,但目前无法获取发行版通过直接 URL 引用识别时使用的 URL 详细信息。

本提案定义了额外的元数据,将由安装前端添加到已安装的发行版中,用于记录直接 URL 来源,供内省已安装软件包数据库的消费者使用(参见 PEP 376)。

动机

本 PEP 的最初动机是允许具有“冻结”操作的工具能够更广泛地重新创建 Python 环境。

具体来说,本 PEP 源于解决 pip 问题 #609 的愿望:即在存在通过直接 URL 引用安装的发行版时改进 pip freeze 的行为。它遵循了 discuss.python.org 上的一个帖子,讨论了实现它的最佳方案。

通过直接 URL 引用进行安装

pip 等 Python 安装程序能够从软件包索引下载和安装发行版。它们还能够从指定源存档和版本控制系统 (VCS) 存储库任意 URL 的要求中下载和安装源代码,这在 PEP440 直接引用 中已标准化。

换句话说,存在两种相关的安装模式。

  1. 要安装的包指定为名称和版本说明符
在这种情况下,安装程序在包索引中查找(或在 pip 的情况下可选地使用 --find-links)以找到要安装的发行版。
  1. 要安装的包指定为直接 URL 引用
在这种情况下,安装程序下载 URL 指定的任何内容(通常是 wheel、源存档或 VCS 存储库)并进行安装。

在这种模式下,安装程序通常会将源代码下载到临时目录中,如果需要,会调用 PEP 517 构建后端生成 wheel,然后安装 wheel,并删除临时目录。

安装后,用户请求下载包的 URL 在用户系统上不留下任何痕迹。

冻结环境

Pip 还有一个名为 pip freeze 的命令,它检查已安装 Python 发行版数据库以生成需求列表。此命令的主要目标是帮助用户生成一个需求列表,该列表以后将允许以最高可能的保真度重新安装相同的环境。

截至 pip 19.3 版本,pip freeze 命令会为每个已安装的发行版(可编辑安装除外)输出一行 name==version。为了实现重新安装相同环境的目标,这要求 (名称, 版本) 元组引用发行版的不可变版本。不变性由 Warehouse 等包索引保证。要使用的包索引通常从安装程序的环​​境或命令行参数中得知。

因此,这种冻结机制对于安装模式 1(即当要安装的包指定为名称加版本说明符时)运行良好。

对于安装模式 2,即当要安装的包指定为直接 URL 引用时,name==version 元组显然不足以重新安装相同的发行版,并且 freeze 命令的用户期望它输出最初请求的 URL。

上述推理同样适用于除 pip freeze 之外的工具,这些工具试图从已安装 Python 发行版数据库生成 Pipfile.lock 或任何其他类似格式。除非另有说明,否则本文档中的“冻结”用作此类操作的通用术语。

从(VCS)URL 安装对于应用程序集成者的重要性

对于应用程序集成商来说,能够可靠地安装和冻结未发布的 Python 发行版版本非常重要。例如,当开发人员需要部署未发布的依赖项修补版本时,通常会直接从包含该修补程序的 VCS 分支安装依赖项,同时等待维护者发布更新版本。

在这种情况下,“冻结”固定已安装的确切 VCS 引用(如果可用,则为提交哈希)非常重要,以便以最高可能的保真度创建可重现的构建。

VCS URL 可用的额外来源元数据

对于 VCS URL,在安装时才有额外可用的源信息,对于内省和某些工作流很有用。例如,当从 VCS URL 安装修订版时,工具可以确定该修订版是否对应于分支、标签或(在 Git 的情况下)ref。此信息可在内省已安装发行版数据库时用于向用户传达有关安装了哪个版本的更多信息(例如,是否安装了分支或标签,如果是,则为分支或标签的名称)。这也允许人们知道是否可以使用标签形式构造 PEP 440 直接引用 URL,因为只有标签才具有不可变语义。

在修订版可变的情况下(例如分支和 Git refs),了解此信息可实现用户可以更新到他们正在跟踪的分支的最新版本,或更新到他们正在本地审查的拉取请求的最新版本的工作流。相反,当修订版是标签时,工具可以提前知道(例如,无需网络调用)不需要更新。

与 URL 本身一样,如果此信息在安装时(VCS 存储库可用时)未记录,则会丢失。

关于“可编辑”安装的说明

pip 的可编辑安装模式大致允许用户将本地目录插入 sys.path 中以用于开发目的。这种模式有些被滥用,以规避从 VCS URL 进行的非可编辑安装在安装后会失去对源的跟踪这一事实。实际上,可编辑安装隐式地在检出目录中记录 VCS 源,因此在运行“冻结”时可以恢复该信息。

这种变通方法的优点是,虽然有用,但很脆弱,混淆了可编辑模式的目的,并且仅在可以使用 setuptools 安装发行版时才有效(即,不适用于其他 PEP 517 构建后端)。

当本 PEP 实施后,将不再需要使用可编辑安装来使 pip freeze 正确处理 VCS 引用。

基本原理

本 PEP 在已安装发行版的 .dist-info 目录中指定了一个新的 direct_url.json 元数据文件。

指定的字段足以重现源存档和 pip 支持的 VCS URL。它们也足以重现 PEP440 直接引用,以及 Pipfile 和 Pipfile.lock 条目。最后,它们足以记录已安装版本的​​分支、标签和/或 Git ref 来源,这些信息由于存在 VCS 检出而已经可用于可编辑安装。

由于已经存在至少三种不同的方式来编码此类信息,本 PEP 使用字典格式,以便不对直接 URL 引用最终必须如何在需求或锁定文件中编码做出任何假设。有关此选择的更多讨论,请参阅下面的替代方案部分。

参考了 Ruby 的 bundler 手册,以验证它是否具有类似的功能,并为本规范中字段的选择和命名提供信息。

JSON 格式允许将来添加额外的字段。

规范

本 PEP 指定在已安装发行版的 .dist-info 目录中创建 direct_url.json 文件,以记录发行版的直接 URL 来源。

此元数据文件的名称和语义的规范来源是《记录已安装发行版的直接 URL 来源》文档。

当安装程序从指定直接 URL 引用(包括 VCS URL)的要求安装发行版时,必须创建此文件。

当从其他类型要求(即名称加版本说明符)安装发行版时,不得创建此文件。

此 JSON 文件必须是一个字典,符合 RFC 8259 并采用 UTF-8 编码。

如果存在,它必须至少包含两个字段。第一个是 url,类型为 string。根据 url 指代的内容,第二个字段必须是 vcs_info(如果 url 是 VCS 引用),archive_info(如果 url 是源存档或 wheel),或 dir_info(如果 url 是本地目录)。这些信息字段的值为一个(可能为空的)子字典,其可能的键定义如下。

url 必须剥离任何敏感的身份验证信息,出于安全原因。

但是,URL 的用户:密码部分可以由环境变量组成,匹配以下正则表达式

\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?

此外,URL 的用户:密码部分可以是众所周知的、非安全敏感的字符串。一个典型的例子是 git,例如在 ssh://git@gitlab.com 这样的 URL 中。

url 指向 VCS 存储库时,必须存在 vcs_info 键,其值为包含以下键的字典

  • 必须存在一个 vcs 键(类型 string),包含 VCS 的名称(即 githgbzrsvn 之一)。其他 VCS 应通过编写 PEP 来修订本规范进行注册。url 值必须与相应的 VCS 兼容,以便安装程序可以将其无需转换地传递给 VCS 的 checkout/download 命令。
  • 一个 requested_revision 键(类型 string)可能存在,命名要安装的分支/标签/ref/提交/修订版/等(以与 VCS 兼容的格式)。
  • 必须存在一个 commit_id 键(类型 string),包含已安装的确切提交/修订号。如果 VCS 支持基于提交哈希的修订标识符,则必须使用此类提交哈希作为 commit_id,以引用已安装源代码的不可变版本。
  • 如果安装程序可以发现有关请求修订版的其他信息,则可以添加 resolved_revision 和/或 resolved_revision_type 字段。如果请求的 URL 中未提供修订版,resolved_revision 可以包含已安装的默认分支,并且 resolved_revision_type 将是 branch。如果安装程序确定 requested_revision 是标签,则可以添加 resolved_revision_type,其值为 tag

url 指向源存档或 wheel 时,必须存在 archive_info 键,其值为包含以下键的字典

  • 应存在一个 hash 键(类型 string),其值为 <hash-algorithm>=<expected-hash>。建议仅使用标准库 hashlib 模块最新版本无条件提供的哈希算法作为源存档哈希。撰写本文时,该列表包括 'md5'、'sha1'、'sha224'、'sha256'、'sha384' 和 'sha512'。

url 指向本地目录时,必须存在 dir_info 键,其值为包含以下键的字典

  • editable(类型:boolean):如果发行版以可编辑模式安装,则为 true,否则为 false。如果省略,默认为 false

url 指向本地目录时,它必须具有 file 方案并符合 RFC 8089。特别是,路径组件必须是绝对路径。将相对路径转换为绝对路径时,应保留符号链接。

注意

当请求的 URL 具有 file:// 方案并指向一个恰好包含 VCS 检出的本地目录时,安装程序不得尝试推断任何 VCS 信息,因此不得在 direct_url.json 中输出任何 VCS 相关信息(例如 vcs_info)。

顶级 subdirectory 字段可能存在,包含一个目录路径,相对于 VCS 存储库、源存档或本地目录的根目录,用于指定 pyproject.tomlsetup.py 的位置。

注意

通常,安装程序在生成 direct_url.json 时应尽可能保留请求 URL 中提供的信息。例如,用户:密码环境变量应保留,并且 requested_revision 应尽可能忠实地反映请求 URL 中提供的修订。但是,此信息会通过更精确的数据(例如 commit_id)进行*丰富*。

已注册的 VCS

本节列出了已注册的 VCS;扩展的、VCS 特定的信息,说明如何使用 vcsrequested_revisionvcs_info 的其他字段;在某些情况下还包括其他 VCS 特定字段。工具可以支持其他 VCS,但建议通过编写 PEP 来修订本规范以进行注册。vcs 字段应为命令名称(小写)。支持此类 VCS 所需的额外字段应以 VCS 命令名称为前缀。

Git

主页

vcs 命令

git

vcs 字段

git

requested_revision 字段

标签名称、分支名称、Git ref、提交哈希、缩短的提交哈希或其他提交类型。

commit_id 字段

提交哈希(40 个十六进制字符的 sha1)。

注意

安装程序可以使用 git show-refgit symbolic-ref 命令来确定 requested_revision 是否对应于 Git ref。反过来,以 refs/tags/ 开头的 ref 对应于标签,而克隆后以 refs/remotes/origin/ 开头的 ref 对应于分支。

Mercurial

主页

vcs 命令

hg

vcs 字段

hg

requested_revision 字段

标签名称、分支名称、变更集 ID、缩短的变更集 ID。

commit_id 字段

变更集 ID(40 个十六进制字符)。

Bazaar

主页

vcs 命令

bzr

vcs 字段

bzr

requested_revision 字段

标签名称、分支名称、修订 ID。

commit_id 字段

修订 ID。

Subversion

主页

vcs 命令

svn

vcs 字段

svn

requested_revision 字段

requested_revision 必须与 svn checkout --revision 选项兼容。在 Subversion 中,分支或标签是 url 的一部分。

commit_id 字段

由于 Subversion 不支持全局唯一标识符,此字段是相应存储库中的 Subversion 修订号。

示例

direct_url.json 示例

源存档

{
    "url": "https://github.com/pypa/pip/archive/1.3.1.zip",
    "archive_info": {
        "hash": "sha256=2dc6b5a470a1bde68946f263f1af1515a2574a150a30d6ce02c6ff742fcc0db8"
    }
}

带标签和提交哈希的 Git URL

{
    "url": "https://github.com/pypa/pip.git",
    "vcs_info": {
        "vcs": "git",
        "requested_revision": "1.3.1",
        "resolved_revision_type": "tag",
        "commit_id": "7921be1537eac1e97bc40179a57f0349c2aee67d"
    }
}

本地目录

{
    "url": "file:///home/user/project",
    "dir_info": {}
}

以可编辑模式安装的本地目录

{
    "url": "file:///home/user/project",
    "dir_info": {
        "editable": true
    }
}

pip 命令示例及其对 direct_url.json 的影响

生成 direct_url.json 的命令

  • pip install https://example.com/app-1.0.tgz
  • pip install https://example.com/app-1.0.whl
  • pip install “git+https://example.com/repo/app.git#egg=app&subdirectory=setup”
  • pip install ./app
  • pip install file:///home/user/app
  • pip install –editable “git+https://example.com/repo/app.git#egg=app&subdirectory=setup”(在这种情况下,url 将是 Git 存储库被克隆到的本地目录,dir_info 将存在并带有 "editable": true,并且不会设置 vcs_info
  • pip install -e ./app

不生成 direct_url.json 的命令

用例

“冻结”环境

诸如 pip freeze 等从已安装 Python 发行版数据库生成需求的工具应在 direct_url.json 存在时加以利用,并优先于版本元数据,以生成更高保真度的输出。在存在 vcs 直接 URL 引用时,应优先使用 commit_id 字段,以提供与原始安装版本最高可能的保真度。如果其需求格式支持,鼓励工具也输出 tag 值(如果存在),因为它具有不可变语义。工具可以根据用户需求选择其他方法。

请注意,本 PEP 的初始迭代并未试图使包含可编辑安装或从本地目录安装的环境可重现,但它试图使它们易于识别。通过本规范的 urldir_info 字段定位本地项目目录,工具可以实现任何适合其用例的策略。

向后兼容性

由于本 PEP 在 .dist-info 目录中指定了一个新文件,因此不存在向后兼容性问题。

备选方案

PEP 426 source_url

现已撤回的 PEP 426 指定了一个 source_url 元数据条目。它也在 distlib 中实现。

它最初旨在用于 sdist,目的略有不同。

此格式缺少对 pip 需求 URL 的 subdirectory 选项的支持。同样的限制也存在于 PEP440 直接引用中。

它还缺少对 URL 的用户:密码部分中的环境变量的显式支持。

对于本 PEP 的使用,必须引入键/值可扩展性机制,并支持 PEP 440 中用户:密码的环境变量。

revision vs ref

保留了 requested_revision 键而不是 requested_ref,因为它是各种 VCS 中更通用的术语,而 refgit 具有特定含义。

致谢

许多人帮助使这个 PEP 成为现实。Paul F. Moore 提供了摘要的精髓。Alyssa Coghlan 建议了 direct_url 名称。


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

最后修改:2025-02-01 08:55:40 GMT