pyproject.toml 规范#

警告

这是一份技术性正式规范。有关 pyproject.toml 的轻松易懂的用户指南,请参阅 编写 pyproject.toml

pyproject.toml 文件充当与打包相关的工具(以及其他工具)的配置文件。

注意

此规范最初在 PEP 518PEP 621 中定义。

pyproject.toml 文件以 TOML 编写。目前指定了三张表,即 [build-system][project][tool]。其他表保留供将来使用(特定于工具的配置应使用 [tool] 表)。

声明构建系统依赖项:[build-system]#

[build-system] 表声明必须安装的任何 Python 级别依赖项,以便成功运行项目的构建系统。

[build-system] 表用于存储与构建相关的数据。最初,该表的只有一个键有效,并且对于该表是必需的:requires。此键必须具有一个字符串列表的值,表示执行构建系统所需的依赖项。此列表中的字符串遵循 版本说明规范

使用 setuptools 构建的项目的示例 [build-system] 表为

[build-system]
# Minimum requirements for the build system to execute.
requires = ["setuptools"]

当不存在 pyproject.toml 文件时,构建工具应将上述示例配置文件用作其默认语义。

工具不应要求存在 [build-system] 表。pyproject.toml 文件可用于存储除构建相关数据之外的其他配置详细信息,因此合理地缺少 [build-system] 表。如果文件存在但缺少 [build-system] 表,则应使用如上所述的默认值。如果指定了表但缺少必需的字段,则工具应将其视为错误。

为了仅出于说明目的提供 TOML 文件中生成数据的特定于类型的表示,以下 JSON Schema 将与数据格式匹配

{
    "$schema": "https://json-schema.fullstack.org.cn/schema#",

    "type": "object",
    "additionalProperties": false,

    "properties": {
        "build-system": {
            "type": "object",
            "additionalProperties": false,

            "properties": {
                "requires": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            },
            "required": ["requires"]
        },

        "tool": {
            "type": "object"
        }
    }
}

声明项目元数据:[project]#

[project] 表指定项目的 核心元数据

元数据有两种:静态动态。静态元数据直接在 pyproject.toml 文件中指定,不能由工具指定或更改(这包括元数据引用的数据,例如元数据引用的文件内容)。动态元数据通过 dynamic 键(在此规范中稍后定义)列出,表示工具稍后将提供的元数据。

隐式地缺少 [project] 表意味着 构建后端 将动态提供所有键。

唯一需要静态定义的键是

  • name

需要但可以静态指定列为动态的键是

  • version

所有其他键都被视为可选,可以静态指定、列为动态或不指定。

[project] 表中允许的键的完整列表是

  • authors

  • classifiers

  • dependencies

  • description

  • dynamic

  • entry-points

  • gui-scripts

  • keywords

  • license

  • maintainers

  • name

  • optional-dependencies

  • readme

  • requires-python

  • scripts

  • urls

  • version

name#

项目名称。

工具应在读取用于内部一致性后立即 规范化 此名称。

version#

版本说明符规范 中定义的项目版本。

用户应优先指定已规范化的版本。

description#

项目的一行摘要说明。如果此摘要包含多行,工具可能会出错。

readme#

项目的完整说明(即 README)。

此键接受字符串或表。如果它是字符串,则它是相对于 pyproject.toml 的路径,指向包含完整说明的文本文件。工具必须假设该文件的编码为 UTF-8。如果文件路径以不区分大小写的 .md 后缀结尾,则工具必须假设内容类型为 text/markdown。如果文件路径以不区分大小写的 .rst 结尾,则工具必须假设内容类型为 text/x-rst。如果工具识别出比此 PEP 更多的扩展名,则它们可以在不将此键指定为 dynamic 的情况下为用户推断内容类型。对于所有未识别的后缀,当未提供内容类型时,工具必须引发错误。

readme 键还可以采用表格。file 键具有一个字符串值,表示相对于 pyproject.toml 的路径,指向包含完整说明的文件。text 键具有一个字符串值,即完整说明。这些键是互斥的,因此如果元数据同时指定这两个键,工具必须引发错误。

readme 键中指定的表格还具有一个 content-type 键,该键采用一个字符串,指定完整说明的内容类型。如果元数据未在表格中指定此键,工具必须引发错误。如果元数据未指定 charset 参数,则假定为 UTF-8。如果工具选择,它们可以支持其他编码。工具可以支持备用内容类型,它们可以将其转换为 核心元数据 支持的内容类型。否则,对于不受支持的内容类型,工具必须引发错误。

requires-python#

项目的 Python 版本要求。

license#

该表格可以具有两个键之一。file 键具有一个字符串值,该值是相对于 pyproject.toml 的文件路径,指向包含项目许可证的文件。工具必须假定该文件的编码为 UTF-8。text 键具有一个字符串值,即项目的许可证。这些键是互斥的,因此如果元数据同时指定这两个键,工具必须引发错误。

authors/maintainers#

被认为是项目“作者”的个人或组织。确切含义可以解释——它可以列出原始或主要作者、当前维护者或软件包所有者。

“maintainers”键与“authors”类似,其确切含义可以解释。

这些键接受一个表格数组,其中包含 2 个键:nameemail。这两个值都必须是字符串。name 值必须是有效的电子邮件名称(即可以在电子邮件中作为名称放置在 RFC 822 中的任何内容),并且不包含逗号。email 值必须是有效的电子邮件地址。这两个键都是可选的,但表格中必须至少指定这两个键中的一个。

使用数据填充核心元数据如下

  1. 如果仅提供name,则值将根据需要放入作者维护者

  2. 如果仅提供email,则值将根据需要放入作者电子邮件维护者电子邮件

  3. 如果同时提供emailname,则值将根据需要放入作者电子邮件维护者电子邮件,格式为{name} <{email}>

  4. 多个值应以逗号分隔。

keywords#

项目的关键字。

classifiers#

适用于该项目的 Trove 分类器。

urls#

一个 URL 表,其中键是 URL 标签,值是 URL 本身。

入口点#

  • TOML类型:表([project.scripts][project.gui-scripts][project.entry-points]

  • 入口点规范

有三个与入口点相关的表。[project.scripts]表对应于入口点规范中的console_scripts组。表的键是入口点的名称,值是对象引用。

[project.gui-scripts]表对应于入口点规范中的gui_scripts组。其格式与[project.scripts]相同。

[project.entry-points]表是一组表。每个子表的名称都是一个入口点组。键和值语义与[project.scripts]相同。用户不得创建嵌套子表,而应将入口点组保持在仅一层深度。

如果元数据定义了[project.entry-points.console_scripts][project.entry-points.gui_scripts]表,则构建后端必须引发错误,因为它们在面对[project.scripts][project.gui-scripts]时会产生歧义。

依赖项/可选依赖项#

项目的(可选)依赖项。

对于 dependencies,它是一个键,其值是字符串数组。每个字符串都表示项目的依赖项,并且必须格式化为有效的 PEP 508 字符串。每个字符串都直接映射到 Requires-Dist 条目。

对于 optional-dependencies,它是一个表,其中每个键指定一个额外项,其值是字符串数组。数组的字符串必须是有效的 PEP 508 字符串。键必须是 Provides-Extra 的有效值。因此,数组中的每个值都成为匹配 Provides-Extra 元数据的相应 Requires-Dist 条目。

dynamic#

指定此 PEP 中列出的哪些键被有意地未指定,以便其他工具可以/将动态提供此类元数据。这清楚地描述了哪些元数据是有意地未指定且预期保持未指定,而不是稍后通过工具提供。

  • 构建后端必须遵守静态指定的元数据(这意味着元数据未在 dynamic 中列出键)。

  • 如果元数据在 dynamic 中指定 name,则构建后端必须引发错误。

  • 如果 核心元数据 规范将某个字段列为“必需”,则元数据必须静态指定键或在 dynamic 中列出它(否则构建后端必须引发错误,即不可能在 [project] 表中以某种方式未列出必需的键)。

  • 如果 核心元数据 规范将某个字段列为“可选”,则如果预期构建后端稍后将提供键的数据,则元数据可以在 dynamic 中列出它。

  • 如果元数据同时静态指定某个键和在 dynamic 中列出它,则构建后端必须引发错误。

  • 如果元数据未在 dynamic 中列出某个键,则构建后端不能代表用户填写必要的元数据(即 dynamic 是允许工具填写元数据的唯一方法,并且用户必须选择填写)。

  • 如果元数据在 dynamic 中指定某个键,但构建后端无法确定其数据(如果确定为准确值,则可以省略数据),则构建后端必须引发错误。

任意工具配置:[tool]#

[tool] 表是与 Python 项目相关的任何工具(不仅仅是构建工具)都可以让用户指定配置数据的地方,只要它们在 [tool] 中使用子表,例如 flit 工具会将其配置存储在 [tool.flit] 中。

需要一种机制在 tool.* 命名空间内分配名称,以确保不同的项目不会尝试使用相同的子表并发生冲突。我们的规则是,如果且仅当项目在 Cheeseshop/PyPI 中拥有 $NAME 的条目时,该项目才能使用子表 tool.$NAME

历史#

  • 2016 年 5 月:pyproject.toml 文件的初始规范,仅包含一个 [build-system],其中包含一个 requires 键和一个 [tool] 表,通过 PEP 518 获得批准。

  • 2020 年 11 月:[project] 表的规范通过 PEP 621 获得批准。