pyproject.toml

从版本 10.0 开始添加。

现代 Python 包可以包含一个 pyproject.toml 文件,它最初在 PEP 518 中引入,后来在 PEP 517PEP 621PEP 660 中扩展。此文件包含构建系统需求和信息,这些信息由 pip 用于构建包。

构建过程

构建包的总体过程是

  • 创建一个隔离的构建环境。

  • 使用构建依赖项填充构建环境。

  • 如果必要且可能,生成包的元数据。

  • 为包生成一个轮子。

如果需要,轮子可以用于执行安装。

构建隔离

对于使用此接口构建包,pip 使用一个隔离环境。也就是说,pip 会在一个临时目录中安装构建时的 Python 依赖项,该目录将被添加到 sys.path 用于构建命令。这确保构建需求独立于用户的运行时环境进行处理。

例如,一个需要旧版 setuptools 才能构建的项目仍然可以安装,即使用户安装了更新的版本(并且不会静默替换该版本)。

构建时依赖项

PEP 518 中引入,pyproject.toml 文件中的 build-system.requires 键是包的构建时依赖项的需求规范列表。

[build-system]
requires = ["setuptools ~= 58.0", "cython ~= 0.29.0"]

构建后端也可以使用 PEP 517get_requires_for_build_wheel 钩子提供动态计算的构建依赖项。此钩子将由 pip 调用,它描述的依赖项也将安装在构建环境中。例如,更新版本的 setuptools 通过此钩子将 setup_requires 的内容公开给 pip。

构建时需求规范遵循 PEP 508,因此可以引用包含 URL 的包。例如

[build-system]
requires = ["setuptools @ git+https://github.com/pypa/setuptools.git@main"]

元数据生成

从版本 19.0 开始添加。

一旦构建环境创建并填充了构建时依赖项,pip 通常需要关于包的元数据(名称、版本、依赖项等等)。

如果 PEP 517prepare_metadata_for_build_wheel 钩子由构建后端提供,则将使用它来生成包的元数据。否则,将生成一个轮子(如下所述),并将其中包含的元数据用于此目的。

轮子生成

从版本 19.0 开始添加。

为了生成轮子,pip 使用 PEP 517build_wheel 钩子,该钩子必须由构建后端提供。构建后端将生成一个轮子,这可能涉及编译用 C/C++(或其他语言)编写的扩展代码。

使用此机制生成的轮子可以 缓存 以供重复使用,以加快未来的安装速度。

可编辑安装

从版本 21.3 开始添加。

对于执行可编辑安装,pip 将使用 PEP 660build_wheel_for_editable 钩子,该钩子必须由构建后端提供。使用此机制生成的轮子不会被缓存。

兼容性回退

如果构建后端缺少此钩子并且项目中存在 setup.py 文件,pip 将回退到旧的基于 setup.py 的可编辑安装。

这被认为是一种权宜之计的解决方案,直到 setuptools 添加对 PEP 660 的支持,届时此功能将被删除;遵循 pip 的常规 弃用策略.

后端配置

构建后端能够接受配置设置,这些设置可以改变构建的处理方式。这些设置采用一系列 key=value 对的形式。用户可以使用 --config-settings 命令行选项提供配置设置(可以多次提供,以指定多个设置)。

提供的配置设置将传递给每个后端钩子调用。

通过 --config-settings 命令行选项(或等效的环境变量或配置文件条目)提供的配置设置将传递给作为 pip 命令行参数明确提供的需求的构建。它们不会传递给依赖项的构建,也不会传递给需求文件中提供的需求的构建。

构建输出

构建后端有责任确保输出采用正确的编码,如 PEP 517 中所述。这可能涉及处理 与 pip 对旧版构建面临的相同挑战.

回退行为

警告

以下片段只是描述了回退行为。有关与 setuptools 一起使用的 pyproject.toml 的有效示例,请参阅 setuptools 文档.

如果一个项目没有 pyproject.toml 文件包含一个 build-system 部分,则假定它具有以下后端设置

[build-system]
requires = ["setuptools>=40.8.0"]
build-backend = "setuptools.build_meta:__legacy__"

如果一个项目具有一个 build-system 部分但没有 build-backend,则

  • 预期它将 setuptools 作为构建需求包含在内。如果可用的 setuptools 版本不够新,则会报告错误。

  • 将使用 setuptools.build_meta:__legacy__ 构建后端。

禁用构建隔离

可以使用 --no-build-isolation 标志禁用它 -- 提供此标志的用户有责任确保构建环境得到适当的管理,包括确保所有必需的构建时依赖项已安装,因为 pip 在传递此标志时不会管理构建时依赖项。

历史记录

由于此功能是逐步推出的,因此在其中已进行了各种显著的更改和改进。

  • setuptools 40.8.0 是第一个提供PEP 517后端的 setuptools 版本,它与直接执行setup.py非常相似。

  • 在 pip 18.0 之前,pip 只支持从轮子中安装构建依赖项,不支持使用环境标记和额外内容(只尊重版本说明符)。

  • 在 pip 18.1 之前,使用.pth文件的构建依赖项不受支持;因此,命名空间包在 Python 3.2 及更早版本中不起作用。