PEP 459 – Python 软件包标准元数据扩展
- 作者:
- Alyssa Coghlan <ncoghlan at gmail.com>
- BDFL 代表:
- Alyssa Coghlan <ncoghlan at gmail.com>
- 讨论列表:
- Distutils-SIG 列表
- 状态:
- 已撤回
- 类型:
- 标准跟踪
- 主题:
- 打包
- 依赖:
- 426
- 创建:
- 2013年11月11日
- 发布历史:
- 2013年12月21日
PEP 撤回
此 PEP 依赖于 PEP 426,该 PEP 本身已被撤回。有关详细信息,请参阅该 PEP 中的 PEP 撤回部分。
同时,元数据扩展将继续像过去 entry_points.txt
等示例那样处理:作为安装到元数据目录中与主 METADATA
文件并排的其他文件。
摘要
此 PEP 描述了 Python 元数据的几个标准扩展。
与所有元数据扩展一样,每个标准扩展格式都独立版本化。更改任何格式都需要更新此 PEP,但不需要更新核心打包元数据。
标准扩展命名空间
Python 包索引上的 python
项目指的是 CPython 参考解释器。此命名空间用作标准元数据扩展的命名空间。
当前定义的标准扩展为
python.details
python.project
python.integrator
python.exports
python.commands
python.constraints
所有标准扩展当前版本均为 1.0
,因此可以省略 extension_metadata
字段而不会丢失任何功能。
python.details
扩展
python.details
扩展允许提供更多有关软件分发的信息。
python.details
扩展包含四个自定义子字段
license
:分发的版权许可证keywords
:分发的包索引关键词classifiers
:分发的包索引 Trove 分类器document_names
:其他元数据文件的名称
所有这些字段都是可选的。如果分发不提供这些字段,则自动化工具必须能够正确运行,包括在请求依赖于这些字段之一的操作时干净地失败。
许可证
一个简短的字符串,总结此分发使用的许可证。
请注意,提供此字段的分发仍然应该在 分类器 字段中指定任何适用的许可证 Trove 分类器。即使有可用的 Trove 分类器,许可证摘要也可以很好地指定该许可证的特定版本,或指示许可证的任何变体或例外情况。
此字段**应该**包含少于 512 个字符,并且**必须**包含少于 2048 个字符。
此字段**不应该**包含任何换行符。
完整的许可证文本**应该**作为分发源代码存档中的单独文件包含。有关详细信息,请参阅 文档名称。
示例
"license": "GPL version 3, excluding DRM provisions"
关键词
其他关键词列表,用于帮助在更大的目录中搜索分发。
示例
"keywords": ["comfy", "chair", "cushions", "too silly", "monty python"]
分类器
字符串列表,每个字符串都提供分发的单个分类值。分类器在 PEP 301 [2] 中进行了描述。
示例
"classifiers": [
"Development Status :: 4 - Beta",
"Environment :: Console (Text Based)",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
]
文档名称
分发 dist-info
元数据目录中包含的支持文档的文件名。
以下支持文档可以命名
description
:包含分发长描述的文件license
:包含分发许可证全文的文件changelog
:描述对分发所做更改的文件
支持文档**必须**直接包含在 dist-info
目录中。文档名称中**不允许**使用目录分隔符。
文件的标记格式(如果有)由文件扩展名指示。这允许索引服务器和其他自动化工具正确呈现包含的文本文档并提供有关呈现错误的反馈,而不是必须猜测预期的格式。
如果文件名没有扩展名,或者扩展名未被识别,则默认呈现格式**必须**为纯文本。
以下标记渲染器**应该**用于指定的文件扩展名
- 纯文本:
.txt
,无扩展名,未知扩展名 - reStructuredText:
.rst
- Markdown:
.md
- AsciiDoc:
.adoc
,.asc
,.asciidoc
- HTML:
.html
,.htm
自动化工具**可以**将一个或多个指定格式呈现为纯文本,并且**可以**呈现超出列出内容的其他标记格式。
自动化工具**不应该**对支持文档内容的最大长度做出任何假设,除非为了保护服务的完整性。
示例
"document_names": {
"description": "README.rst",
"license": "LICENSE.rst",
"changelog": "NEWS"
}
python.project
扩展
python.project
扩展允许提供更多有关分发创建和维护的信息。
python.project
扩展包含三个自定义子字段
contacts
:分发的关键联系点contributors
:分发的其他贡献者project_urls
:分发的相关 URL
联系信息
个人和组织的详细信息以映射的形式记录,其中包含以下子字段
name
:个人或群体的名称email
:电子邮件地址(这可能是邮件列表)url
:URL(例如源代码托管服务上的个人资料页面)role
:"author"
、"maintainer"
或"contributor"
之一
name
子字段是必需的,其他子字段是可选的。
如果未声明特定角色,则默认为 contributor
。
电子邮件地址必须采用 local-part@domain
的形式,其中 local-part 的长度最多为 64 个字符,整个电子邮件地址的字符数不超过 254 个。格式的正式规范在 RFC 5322(第 3.2.3 节和 3.4.1 节)和 RFC 5321 中,在信息性 RFC 3696 和相关勘误中给出了更易读的形式。
定义的贡献者角色如下
author
:分发的原始创建者maintainer
:分发的当前主要贡献者,当他们不是原始创建者时contributor
:参与分发创建的其他个人或组织
联系人和贡献者元数据是可选的。如果分发不提供这些字段,则自动化工具必须能够正确运行,包括在请求依赖于这些字段之一的操作时干净地失败。
联系人
贡献者条目列表,提供获取有关项目更多信息的推荐联系点。
下面的示例适用于一个项目,该项目正在从原始作者手中移交给新的主要维护者,同时作为更大的开发组的一部分进行操作。
示例
"contacts": [
{
"name": "Python Packaging Authority/Distutils-SIG",
"email": "distutils-sig@python.org",
"url": "https://bitbucket.org/pypa/"
},
{
"name": "Samantha C.",
"role": "maintainer",
"email": "dontblameme@example.org"
},
{
"name": "Charlotte C.",
"role": "author",
"email": "iambecomingasketchcomedian@example.com"
}
]
贡献者
其他贡献者的贡献者条目列表,这些贡献者尚未列为当前项目联系点。列表元素中的子字段与主联系人字段的子字段相同。
示例
"contributors": [
{"name": "John C."},
{"name": "Erik I."},
{"name": "Terry G."},
{"name": "Mike P."},
{"name": "Graeme C."},
{"name": "Terry J."}
]
项目 URL
任意文本标签到与项目相关的其他 URL 的映射。
虽然项目可以自由选择自己的标签和特定 URL,但**建议**使用以下示例中的标签提供主页、源代码控制、问题跟踪器和文档链接。
URL 标签**必须**由自动化工具视为不区分大小写,但它们不需要是有效的 Python 标识符。任何合法的 JSON 字符串都允许作为 URL 标签。
示例
"project_urls": {
"Documentation": "https://distlib.readthedocs.org",
"Home": "https://bitbucket.org/pypa/distlib",
"Repository": "https://bitbucket.org/pypa/distlib/src",
"Tracker": "https://bitbucket.org/pypa/distlib/issues"
}
python.integrator
扩展
在结构上,此扩展与 python.project
扩展非常相似(扩展名称是唯一的区别)。
但是,project
元数据指的是软件的上游创建者,而 integrator
元数据指的是修改版本的下游重新分发者。
如果软件正在未经修改地重新分发,则通常不会使用此扩展。但是,如果软件已打补丁(例如,从更高版本回移植兼容的修复程序,或解决平台兼容性问题),则**应该**使用此扩展,并在分发的版本标识符中添加本地版本标签。
如果链中有多个重新分发者,则每个重新分发者只需使用其特定的元数据覆盖此扩展。
python.exports
扩展
大多数 Python 分发通过 Python 模块命名空间公开包和模块以供导入。分发在安装时也可能公开其他接口。
python.exports
扩展包含三个自定义子字段
modules
:分发导出的模块namespaces
:分发贡献到的命名空间包exports
:发行版导出的其他 Python 接口
导出说明符
导出说明符是一个字符串,由一个完全限定名称以及一个可选的括在方括号中的额外名称组成。这为导出说明符提供了以下四种可能的格式
module
module:name
module[requires_extra]
module:name[requires_extra]
注意
jsonschema 文件目前使用 Python 2 ASCII 标识符规则来限制限定名称。鉴于 Python 3 中更宽松的标识符规则,可能需要重新考虑这一点。
子字段的含义如下
module
:提供导出的模块name
:如果适用,则为模块内导出的完全限定名称requires_extra
:指示导出只有在给定额外名称中指定的额外依赖项在已安装的环境中可用时才能正常工作
注意
我尝试将其作为具有子字段的映射,但这使得下面的示例难以阅读。虽然此 PEP 主要用于工具使用,但可读性对于某些调试目的仍然很重要,并且因为我期望格式的片段将在其他地方重复使用。
模块
发行版为导入提供的模块和包的限定名称列表。
注意
jsonschema 文件目前使用 Python 2 ASCII 标识符规则来限制限定名称。鉴于 Python 3 中更宽松的标识符规则,可能需要重新考虑这一点。
对于包含点的名称,点之前的名称部分必须出现在已安装的模块列表或命名空间包列表中。
为了帮助避免名称冲突,建议发行版提供一个与发行版名称匹配的单个顶级模块或包(或其小写等效项)。这要求发行版名称也满足 Python 标识符的要求,这些要求比发行版名称的要求更严格)。此做法还有助于更容易找到模块的权威来源。
索引服务器应允许多个发行版发布相同的模块,但可以通知发行版作者潜在的冲突。
安装工具在被要求安装一个提供模块的发行版时,而该模块也被另一个已安装的发行版提供时,应报告错误。
请注意,如果未安装相应的额外内容,则尝试导入某些声明的模块可能会导致异常。
示例
"modules": ["chair", "chair.cushions", "python_sketches.nobody_expects"]
注意
将其作为导出说明符列表将允许发行版声明特定模块需要哪个额外内容才能正确运行。另一方面,有人认为,这正是值得将单独的发行版拆分出来而不是使用额外内容的地方。
命名空间
发行版为其贡献模块的命名空间包的限定名称列表。
注意
jsonschema 文件目前使用 Python 2 ASCII 标识符规则来限制限定名称。鉴于 Python 3 中更宽松的标识符规则,可能需要重新考虑这一点。
在 Python 3.3 之前的 Python 版本(提供本地命名空间包支持)中,安装工具应发出合适的__init__.py
文件以正确初始化命名空间,而不是使用发行版提供的文件。
如果发行版声明的命名空间包与已安装模块的名称冲突,反之亦然,则安装工具应发出警告,并可以发出错误。
示例
"namespaces": ["python_sketches"]
导出
exports
字段是一个包含前缀名称作为键的映射。每个键标识一个导出组,其中包含发行版发布的一个或多个导出。
导出组名称由发行版定义,这些发行版将以某种方式利用发布的导出信息。主要用例是支持插件模型的发行版:定义导出组允许其他发行版指示它们提供的插件、如何导入和访问这些插件,以及插件正常工作所需的任何额外依赖项(如果有)。
为了减少名称冲突的可能性,导出组名称应使用与定义导出组含义的发行版中的模块名称相对应的前缀。此做法还有助于更容易找到导出组的权威文档。
然后,每个单独的导出组都是任意非空字符串键到导出说明符的映射。导出组内导出名称的含义取决于定义导出组的发行版。为导出名称格式创建适当的定义可以允许导入的发行版确定导出是否相关,而无需导入每个导出模块。
示例
"exports": {
"nose.plugins.0.10": {
"chairtest": "chair:NosePlugin"
}
}
python.commands
扩展
python.commands
扩展包含三个自定义子字段
wrap_console
:安装程序要生成的控制台包装脚本wrap_gui
:安装程序要生成的 GUI 包装脚本prebuilt
:发行版的构建过程创建并直接安装到配置的脚本目录中的脚本
wrap_console
和wrap_gui
都是脚本名称到导出说明符的映射。脚本名称必须遵循与发行版名称相同的命名规则。
包装脚本的导出说明符必须引用具有 __main__ 子模块的包(如果在导出说明符中未给出name
子字段),或者引用命名模块内的可调用对象。
安装工具应在安装过程中生成相应的包装器。
注意
仍然需要更多关于“适当包装器”的含义的细节。目前,请参考 setuptools 和 zc.buildout 生成的包装脚本。
prebuilt
是脚本路径的列表,相对于 wheel 文件中的脚本目录或安装后的脚本目录。它们仅出于信息目的提供 - 安装它们通过构建发行版时创建的文件的正常流程来处理。
构建工具应将此扩展标记为需要安装程序处理。
索引服务器应允许多个发行版发布相同的命令,但可以通知发行版作者潜在的冲突。
安装工具在被要求安装一个提供命令的发行版时,而该命令也被另一个已安装的发行版提供时,应报告错误。
示例
"python.commands": {
"installer_must_handle": true,
"wrap_console": [{"chair": "chair:run_cli"}],
"wrap_gui": [{"chair-gui": "chair:run_gui"}],
"prebuilt": ["reduniforms"]
}
python.constraints
扩展
python.constraints
扩展包含两个自定义子字段
environments
:支持的安装环境extension_metadata
:其他已安装组件发布的扩展元数据字段中所需的精确匹配
构建工具应将此扩展标记为需要安装程序处理。
索引服务器应允许上传具有无法使用该索引满足的约束的发行版,但可以通知发行版作者任何此类潜在的兼容性问题。
如果发行版指定了约束,并且目标安装环境未能满足这些约束,则安装工具应报告错误,至少必须发出警告,并且可以允许用户强制安装继续进行,而不管约束是否满足。
示例
"python.constraints": {
"installer_must_handle": true,
"environments": ["python_version >= 2.6"],
"extension_metadata": {
"fortranlib": {
"fortranlib.compatibility": {
"fortran_abi": "openblas-g77"
}
}
}
}
支持的环境
environments
子字段是一个字符串列表,指定发行版明确支持的环境。如果环境与给定的环境标记中的至少一个匹配,则认为该环境受支持。
如果元数据中未给出此字段,则假定发行版支持 Python 支持的任何平台。
各个条目是环境标记,如PEP 426中所述。
此字段的两个主要用途是声明支持的 Python 版本和支持的基础操作系统。
指示支持的 Python 版本的示例
# Supports Python 2.6+
"environments": ["python_version >= '2.6'"]
# Supports Python 2.6+ (for 2.x) or 3.3+ (for 3.x)
"environments": ["python_version >= '3.3'",
"'3.0' > python_version >= '2.6'"]
指示支持的操作系统的示例
# Windows only
"environments": ["sys_platform == 'win32'"]
# Anything except Windows
"environments": ["sys_platform != 'win32'"]
# Linux or BSD only
"environments": ["'linux' in sys_platform",
"'bsd' in sys_platform"]
支持的 Python 版本因平台而异的示例
# The standard library's os module has long supported atomic renaming
# on POSIX systems, but only gained atomic renaming on Windows in Python
# 3.3. A distribution that needs atomic renaming support for reliable
# operation might declare the following supported environments.
"environment": ["python_version >= '2.6' and sys_platform != 'win32'",
"python_version >= '3.3' and sys_platform == 'win32'"]
扩展元数据约束
extension_metadata
子字段是从发行版名称到扩展元数据片段的映射,这些片段预计与目标安装环境中命名发行版的元数据完全匹配。
然后,每个子映射由一个从元数据扩展名称到字段子集的预期精确值的映射组成。
例如,名为fortranlib
的发行版可能会发布不同的 FORTRAN ABI,具体取决于其构建方式,并且安装到同一运行时环境中的任何相关项目都应使用匹配的构建选项。这可以通过让基本发行版发布一个自定义扩展来处理,该扩展指示用于创建二进制扩展的构建选项
"extensions": {
"fortranlib.compatibility": {
"fortran_abi": "openblas-g77"
}
}
包含需要与基本发行版兼容的二进制扩展的其他发行版将在其自己的元数据中定义合适的约束
"python.constraints": {
"installer_must_handle": true,
"extension_metadata": {
"fortranlib": {
"fortranlib.compatibility": {
"fortran_abi": "openblas-g77"
}
}
}
}
此约束指定
fortranlib
必须安装(这也应表示为正常的依赖项,以便安装程序确保满足它)- 已安装的
fortranlib
版本必须在其发布的元数据中包含自定义fortranlib.compatibility
扩展 - 该扩展的
fortan_abi
子字段必须具有完全相同的openblas-g77
值。
如果满足所有这些条件(已安装发行版,元数据中包含指定的扩展,指定的子字段具有指定的精确值),则认为约束已满足。
注意
此处的主要预期用例是允许具有其他 ABI 兼容性要求的 C 扩展以任何安装工具都无需了解详细信息的方式声明这些要求。特别是,许多基于 NumPy 的科学库需要使用一组一致的 FORTRAN 库构建,因此有“fortranlib”示例。
这就是不支持模式匹配或布尔逻辑的原因:即使此扩展的“简单”版本也相对复杂,并且目前没有令人信服的理由使其比现在更复杂。
版权
本文档已置于公共领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0459.rst