直接 URL 数据结构

本文档指定了一种 JSON 可序列化的抽象数据结构,可以表示指向 Python 项目和分发工件的 URL,例如 VCS 源代码树、本地源代码树、源代码分发和 Wheel 包。

在撰写本文时,尚未正式指定如何将此数据结构的各个部分合并为可传递给工具的单个 URL。一种常见的表示是 pip URL 格式 (VCS 支持),其他示例在版本说明符规范中提供。

规范

直接 URL 数据结构必须是一个字典,根据RFC 8259可序列化为 JSON。

它必须至少包含两个字段。第一个是url,类型为string。其内容必须是符合WHATWG URL 标准的有效 URL。

根据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/user/repo这样的 URL。

VCS URL

url引用 VCS 仓库时,vcs_info键必须以字典形式存在,并包含以下键

  • 必须存在一个vcs键(类型为string),包含 VCS 的名称(即githgbzrsvn之一)。其他 VCS 应通过编写 PEP 来修订此规范以进行注册。url值必须与相应的 VCS 兼容,以便安装程序可以将其直接传递给 VCS 的 checkout/download 命令。

  • 可以存在一个requested_revision键(类型为string),命名分支/标签/引用/提交/修订等(格式与 VCS 兼容)。此字段必须与用户请求的修订版本匹配,并且当用户未选择特定修订版本时,此字段不得存在。

  • 必须存在一个commit_id键(类型为string),包含已安装/将要安装的精确提交/修订号。如果 VCS 支持基于提交哈希的修订标识符,则必须使用该提交哈希作为commit_id,以引用源代码的不可变版本。

归档 URL

url引用源代码归档或 wheel 包时,archive_info键必须以字典形式存在,并包含以下键

  • 应存在一个hashes键,其值为一个字典,将哈希名称映射到文件的十六进制编码摘要。

    可以包含多个哈希,消费者可以自行决定如何处理多个哈希(它可能会验证所有哈希或其中的一部分,或者根本不验证)。

    这些哈希名称应始终标准化为小写。

    任何通过hashlib可用的哈希算法(特别是任何可以传递给hashlib.new()且不需要额外参数的算法)都可以用作哈希字典的键。应始终至少包含一个来自hashlib.algorithms_guaranteed的安全算法。在撰写本文时,特别推荐使用sha256

  • 出于向后兼容性目的,可以存在一个已弃用的hash键(类型为string),其值为<hash-algorithm>=<expected-hash>

数据结构的生产者应在可用一个或多个哈希时发出hashes键。生产者应在之前发出hash键的上下文中继续发出该键,以保持与现有客户端的向后兼容性。

hashhashes键都存在时,hash键中表示的哈希也必须存在于hashes字典中,这样消费者就可以在hashes键存在时只考虑它,否则回退到hash

本地目录

url引用本地目录时,dir_info键必须以字典形式存在,并包含以下键

  • editable(类型:boolean):如果分发已/将以可编辑模式安装,则为true,否则为false。如果缺失,默认为false

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

子目录中的项目

可以存在一个顶层subdirectory字段,包含一个目录路径,该路径相对于 VCS 仓库、源代码归档或本地目录的根目录,用于指定pyproject.tomlsetup.py的位置。

已注册的 VCS

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

Git

主页

https://git-scm.cn/

vcs 命令

git

vcs字段

git

requested_revision字段

标签名、分支名、Git 引用、提交哈希、缩短的提交哈希或其他 commit-ish。

commit_id字段

提交哈希(40 位十六进制 SHA1)。

注意

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

Mercurial

主页

https://www.mercurial-scm.org/

vcs 命令

hg

vcs字段

hg

requested_revision字段

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

commit_id字段

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

Bazaar

主页

https://www.breezy-vcs.org/

vcs 命令

bzr

vcs字段

bzr

requested_revision字段

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

commit_id字段

修订 ID。

Subversion

主页

https://subversion.org.cn/

vcs 命令

svn

vcs字段

svn

requested_revision字段

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

commit_id字段

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

JSON 模式

以下 JSON 模式可用于验证direct_url.json的内容

{
  "$schema": "https://json-schema.fullstack.org.cn/draft/2019-09/schema",
  "$id": "https://packaging.pythonlang.cn/en/latest/specifications/schemas/direct-url.schema.json",
  "title": "Direct URL Data",
  "description": "Data structure that can represent URLs to python projects and distribution artifacts such as VCS source trees, local source trees, source distributions and wheels.",
  "definitions": {
    "url": {
      "type": "string",
      "format": "uri"
    },
    "DirInfo": {
      "type": "object",
      "properties": {
        "editable": {
          "type": ["boolean", "null"]
        }
      }
    },
    "VCSInfo": {
      "type": "object",
      "properties": {
        "vcs": {
          "type": "string",
          "enum": ["git", "hg", "bzr", "svn"]
        },
        "requested_revision": {
          "type": "string"
        },
        "commit_id": {
          "type": "string"
        },
        "resolved_revision": {
          "type": "string"
        }
      },
      "required": ["vcs", "commit_id"]
    },
    "ArchiveInfo": {
      "type": "object",
      "properties": {
        "hash": {
          "type": "string",
          "pattern": "^\\w+=[a-f0-9]+$",
          "deprecated": true
        },
        "hashes": {
          "type": "object",
          "patternProperties": {
            "^[a-f0-9]+$": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "allOf": [
    {
      "type": "object",
      "properties": {
        "url": {
          "$ref": "#/definitions/url"
        }
      },
      "required": ["url"]
    },
    {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "dir_info": {
              "$ref": "#/definitions/DirInfo"
            }
          },
          "required": ["dir_info"]
        },
        {
          "type": "object",
          "properties": {
            "vcs_info": {
              "$ref": "#/definitions/VCSInfo"
            }
          },
          "required": ["vcs_info"]
        },
        {
          "type": "object",
          "properties": {
            "archive_info": {
              "$ref": "#/definitions/ArchiveInfo"
            }
          },
          "required": ["archive_info"]
        }
      ]
    }
  ]
}

示例

源归档

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

带标签和提交哈希的 Git URL

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

本地目录

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

可编辑模式的本地目录

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

历史

  • 2020 年 3 月:此规范通过PEP 610获得批准,定义了direct_url.json元数据文件。

  • 2023 年 1 月:添加了archive_info.hashes键(讨论)。