记录已安装项目¶
本文档规定了一种通用格式,用于记录环境中安装的 Python 项目的信息。通用的元数据格式允许工具查询、管理或卸载项目,无论它们是如何安装的。
几乎所有信息都是可选的。这允许 Python 生态系统之外的工具(例如 Linux 包管理器)尽可能地与 Python 工具集成。例如,即使安装程序无法以 Python 工具特有的格式轻松提供已安装文件的列表,它仍应记录已安装项目的名称和版本。
.dist-info 目录¶
从分发包安装的每个项目,除了文件之外,还必须安装一个与可导入模块和包并置的“.dist-info”目录(通常是 site-packages 目录)。
此目录命名为 {name}-{version}.dist-info,其中 name 和 version 字段对应于 核心元数据规范。两个字段都必须标准化(参见名称标准化规范和版本标准化规范),并将破折号 (-) 字符替换为下划线 (_) 字符,因此 .dist-info 目录在其主干中总是只有一个破折号 (-) 字符,用于分隔 name 和 version 字段。
从历史上看,工具未能替换 name 字段中的点字符或标准化大小写,或者未在 version 字段中执行标准化。使用 .dist-info 目录的工具应期望这些字段未标准化,并将其视为与其标准化对应项等效。写入 .dist-info 目录的新工具必须使用上述规则标准化 name 和 version 字段,并且鼓励现有工具开始标准化这些字段。
注意
“.dist-info”目录的名称经过格式化,以明确表示分发包作为文件系统路径。向用户显示分发包名称的工具应避免使用标准化名称,而应显示指定的名称(在需要解析到已安装包之前),或者读取核心元数据中的相应字段,因为其中列出的值未转义,并准确反映了分发包。库应为这些工具提供 API 以供使用,以便工具在显示分发包信息时可以访问未标准化的名称。
此 .dist-info 目录可能包含以下文件,详情如下
METADATA:包含项目元数据RECORD:记录已安装文件的列表。INSTALLER:记录用于安装项目的工具名称。entry_points.txt:详见入口点规范direct_url.json:详见记录已安装分发包的直接 URL 来源
METADATA 文件是强制性的。所有其他文件可由安装工具自行决定省略。可能存在额外的特定于安装程序的文件。
此 .dist-info/ 目录可能包含以下目录,详述如下
licenses/:包含许可证文件。sboms/:包含软件物料清单文件(SBOM)。
本规范的早期版本还规定了一个 REQUESTED 文件。此文件现在被视为工具特定的扩展,但未来可能会再次标准化。请参阅 PEP 376 了解其原始含义。
METADATA 文件¶
METADATA 文件包含 核心元数据规范 1.1 或更高版本中描述的元数据。
METADATA 文件是强制性的。如果无法创建,或者如果必需的核心元数据不可用,安装程序必须报告错误并停止安装项目。
RECORD 文件¶
RECORD 文件包含已安装文件的列表。它是一个 CSV 文件,每行包含一个记录(已安装文件)。
CSV 方言必须可以通过 Python 的 csv 模块的默认 reader 读取
字段分隔符:
,(逗号),引用字符:
"(直双引号),行终止符:
\r\n或\n。
每条记录由三个元素组成:文件的路径、内容的哈希值和文件大小。
路径可以是绝对路径,也可以是相对于包含 .dist-info 目录的路径(通常是 site-packages 目录)。在 Windows 上,目录可以使用正斜杠或反斜杠 (/ 或 \) 分隔。
哈希值可以是一个空字符串,或者是一个来自 hashlib.algorithms_guaranteed 的哈希算法名称,后面跟着等号字符 = 和文件内容的摘要,使用 urlsafe-base64-nopad 编码(base64.urlsafe_b64encode(digest) 并移除尾随的 =)。
大小可以是一个空字符串,也可以是文件大小(以字节为单位),表示为十进制整数。
对于任何文件,哈希值和大小字段中的一个或两个都可以留空。通常,.pyc 文件和 RECORD 文件本身的条目具有空的哈希值和大小。对于其他文件,不建议省略这些信息,因为它会阻止验证已安装项目的完整性。
如果 RECORD 文件存在,它必须列出项目的所有已安装文件,除了与 RECORD 中列出的 .py 文件对应的 .pyc 文件(后者是可选的)。值得注意的是,.dist-info 目录的内容(包括 RECORD 文件本身)必须被列出。不应列出目录。
要完全卸载一个包,工具需要删除 RECORD 中列出的所有文件,所有与已删除的 .py 文件对应的 .pyc 文件(所有优化级别),以及因卸载而清空的任何目录。
以下是一个可能的 RECORD 文件示例片段
/usr/bin/black,sha256=iFlOnL32lIa-RKk-MDihcbJ37wxmRbE4xk6eVYVTTeU,220
../../../bin/blackd,sha256=lCadt4mcU-B67O1gkQVh7-vsKgLpx6ny1le34Jz6UVo,221
__pycache__/black.cpython-38.pyc,,
__pycache__/blackd.cpython-38.pyc,,
black-19.10b0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
black-19.10b0.dist-info/licenses/LICENSE,sha256=nAQo8MO0d5hQz1vZbhGqqK_HLUqG1KNiI9erouWNbgA,1080
black-19.10b0.dist-info/METADATA,sha256=UN40nGoVVTSpvLrTBwNsXgZdZIwoKFSrrDDHP6B7-A0,58841
black-19.10b0.dist-info/RECORD,,
black.py,sha256=45IF72OgNfF8WpeNHnxV2QGfbCLubV5Xjl55cI65kYs,140161
blackd.py,sha256=JCxaK4hLkMRwVfZMj8FRpRRYC0172-juKqbN22bISLE,6672
blib2to3/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8
blib2to3/__pycache__/__init__.cpython-38.pyc,,
blib2to3/__pycache__/pygram.cpython-38.pyc,sha256=zpXgX4FHDuoeIQKO_v0sRsB-RzQFsuoKoBYvraAdoJw,1512
blib2to3/__pycache__/pytree.cpython-38.pyc,sha256=LYLplXtG578ZjaFeoVuoX8rmxHn-BMAamCOsJMU1b9I,24910
blib2to3/pygram.py,sha256=mXpQPqHcamFwch0RkyJsb92Wd0kUP3TW7d-u9dWhCGY,2085
blib2to3/pytree.py,sha256=RWj3IL4U-Ljhkn4laN0C3p7IRdfvT3aIRjTV-x9hK1c,28530
如果 RECORD 文件缺失,依赖 .dist-info 的工具不得尝试卸载或升级包。(此限制不适用于依赖其他信息源的工具,例如 Linux 发行版中的系统包管理器。)
注意
强烈不鼓励已安装的包自行修改(例如,在 site-packages 中的其命名空间下存储缓存文件)。site-packages 内部的更改应留给像 pip 这样的专用安装工具。如果一个包仍然以这种方式被修改,那么 RECORD 必须被更新,否则卸载包将留下未列出的文件(可能导致僵尸命名空间包)。
INSTALLER 文件¶
如果存在,INSTALLER 是一个单行文本文件,其中包含用于安装项目的工具名称。如果安装程序可以通过命令行执行,INSTALLER 应该包含命令名称。否则,它应该包含一个可打印的 ASCII 字符串。
文件可以由零个或多个 ASCII 空白字符终止。
以下是两个可能的 INSTALLER 文件示例
pip
MegaCorp Cloud Install-O-Matic
此值仅用于信息目的。例如,如果要求一个工具卸载项目但找不到 RECORD 文件,它可能会建议 INSTALLER 中命名的工具可能能够进行卸载。
entry_points.txt 文件¶
此文件可由安装程序创建,以指示包何时包含旨在由其他代码发现和使用的组件,包括控制台脚本和安装程序已提供执行的其他应用程序。
其详细规范位于 入口点规范。
direct_url.json 文件¶
当从指定直接 URL 引用(包括 VCS URL)的要求安装分发包时,安装程序必须创建此文件。
当从其他类型的要求(即名称加版本说明符)安装分发包时,不得创建此文件。
其详细规范位于 记录已安装分发包的直接 URL 来源。
licenses/ 子目录¶
如果元数据版本为 2.4 或更高,并且指定了一个或多个 License-File 字段,则 .dist-info/ 目录必须包含一个 licenses/ 子目录,该子目录必须包含 METADATA 文件中 License-File 字段中列出的文件,其路径相对于 licenses/ 目录。此目录中的任何文件都必须由安装工具从 wheels 中复制。
sboms/ 子目录¶
.dist-info/sboms/ 目录中包含的所有文件必须是软件物料清单 (SBOM) 文件,描述已安装包中包含的软件。此目录中的任何文件都必须由安装工具从 wheels 中复制。
有意阻止更改已安装的包¶
在某些情况下(例如,需要管理外部依赖项以及 Python 生态系统依赖项时),安装包到 Python 环境的工具希望确保其他工具不用于卸载或以其他方式修改已安装的包,因为这样做可能会导致与更广泛环境的兼容性问题。
为实现此目的,受影响的工具应采取以下步骤
重命名或删除
RECORD文件,以防止通过其他工具进行更改(例如,添加后缀以创建非标准的RECORD.tool文件,如果工具本身需要该信息,或者如果包内容通过其他方式跟踪和管理,则完全省略该文件)写入
INSTALLER文件,指示应用于管理包的工具名称(这允许了解RECORD的工具在被要求修改受影响的包时提供更好的错误通知)
Python 运行时提供商还可以通过修改默认的 Python 包安装方案,使其使用不同于平台提供包的位置(同时确保这两个位置都出现在默认的 Python 导入路径上),来防止无意中修改平台提供的包。
在某些情况下,甚至可能需要阻止通过 Python 特定工具安装额外的包。对于这些情况,请参阅外部管理环境
历史¶
2009 年 6 月:本规范的原始版本通过 PEP 376 获得批准。当时,它被称为 已安装 Python 分发数据库。
2020 年 3 月:
direct_url.json文件的规范通过 PEP 610 获得批准。它仅在本页面中提及;有关完整定义,请参阅 记录已安装分发包的直接 URL 来源。2020 年 9 月:各项修订和澄清通过 PEP 627 获得批准。
2024 年 12 月:
.dist-info/licenses/目录通过 PEP 639 进行了规范。