构建系统接口

在处理可安装的包源代码发行版时,pip 不会直接处理包的构建过程。这个责任被委托给“构建后端”——也称为“构建系统”。这意味着 pip 需要一个接口来与这些构建后端交互。

pip 使用两个主要接口来进行这些交互

pyproject.toml based

标准支持的接口,具有明确的构建依赖项声明和管理。

setup.py based

遗留接口,我们正在努力迁移用户。没有好的机制来声明构建依赖项。

有关各个接口的详细信息,可以在上面链接的各自页面中找到。本文档涵盖了 pip 将为项目使用哪种构建系统接口的细微差别,以及适用于 pip 可能使用的所有构建系统接口的详细信息。

确定使用哪种构建系统接口

目前,如果存在 pyproject.toml 文件,pip 使用 pyproject.toml 基于的构建系统接口。如果没有,则使用遗留构建系统接口。我们的目标是在将来的某个时间点无条件地切换到使用 pyproject.toml 构建系统接口,并放弃对遗留构建系统接口的支持。

在执行构建时,pip 会提到它正在使用哪个构建系统接口。通常,这将采用类似以下消息的形式

Building wheel for pip (pyproject.toml)... done
Building wheel for pip (setup.py)... done

方括号中的内容指的是正在使用的构建系统接口。

在版本 21.3 中更改: 输出使用“pyproject.toml”代替“PEP 517”来表示 pyproject.toml 基于的构建系统接口。

控制使用哪种构建系统接口

--use-pep517 标志(以及对应的环境变量:PIP_USE_PEP517)可用于强制所有包使用 pyproject.toml 基于的构建系统接口。目前没有办法强制使用遗留构建系统接口。

控制 setup_requires

提示

这仅与使用 setuptools 作为构建后端并使用 setup_requires 关键字参数在其 setup.py 文件中的项目相关。

setup_requires 参数在 setup.py 中用于指定包的构建时依赖项。这已被 pyproject.toml 文件中的 build-system.requires 键(根据 PEP 518)取代。但是,在某些情况下,你可能会遇到使用 setup_requires 的包(例如:该包尚未更新以使用新的方法!)。

如果你控制该包,请考虑添加一个 pyproject.toml 文件以利用现代构建系统接口。这将通过推迟到 pip 进行安装来避免调用有问题的行为。

对于最终用户,处理使用 setup_requires 的包的最佳解决方案是在之前使用 pip install 命令安装 setup_requires 中列出的包。这是因为无法控制 easy_install 如何定位这些依赖项,或者 setuptools 如何使用 pip 的命令行选项调用 pip——这使得很难让一切正常工作。

如果你希望确保 easy_install 调用不会访问 PyPI,你需要使用 distutils 配置文件 配置其行为。以下是一些示例

  • easy_install 在备用索引中定位依赖项

    [easy_install]
    index_url = https://my.index-mirror.com
    
  • 让依赖项来自本地目录而不是爬取 PyPI,添加以下内容

    [easy_install]
    allow_hosts = ''
    find_links = file:///path/to/local/archives/
    

历史背景

setuptools < 52.0 将使用 easy_install 尝试满足 setup_requires 依赖项,这会导致奇怪的错误——easy_install 不理解许多现代 Python 打包标准,通常会尝试安装不兼容的包版本或错误地构建包。它还会生成不正确的脚本包装器,这些包装器在许多情况下无法正常工作。

较新版本的 setuptools 将使用 pip 进行这些安装,但对传递任何命令行参数的能力有限。这也会导致奇怪的错误和微妙的不正确行为。