Python构建系统的各个部分

372 阅读3分钟

Python包的构建是一些不同的工具在标准化过程中协调的产物。作为一个包的作者,你最大的选择之一是使用哪一套工具。评估每个工具的细微差别是很困难的,尤其是当你是打包新手的时候。幸运的是,各种工具正在围绕相同的核心工作流程进行标准化,所以一旦你学会了它,你就能以最小的努力在各种工具之间进行切换。

这篇文章涵盖了你首先需要学习的关于Python构建系统本身的部分。

要跟上这篇文章,你需要安装和使用 build。如果你以前没有做过,请看下面的步骤。

安装 build

build(github.com/pypa/build) 是 Python Packaging Authority (PyPA) 提供的一个工具,用于构建 Python 包。

使用下面的命令安装 build:

 python -m pip install build

为了验证你的配置,运行下面的命令:

 $ python -m build—version

在你的软件包的根目录下,先用下面的命令运行build

 $ python -m build-build

因为你的包还没有内容,你应该看到一个类似下面的错误:

 ERROR Source /Users/<you>/code/first-python-package does not appear to be
 <linearrow /> a Python project: no pyproject.toml or setup.py

输出中提出了两个文件建议。pyproject.toml 是 PEP 518(https://www.python.org/dev/peps/pep-0518/) 中引入的用于配置 Python 打包的较新的标准文件,除非你想使用的第三方工具只与setup.py 兼容,否则应该优先使用。该文件使用 TOML(https://toml.io/en/),一种类似 INI 的语言,将配置分成相关部分。使用以下命令创建pyproject.toml 文件,以纠正错误。

 $ touch pyproject.toml

再次运行build 命令。这一次,构建应该成功运行,你应该看到大量的输出,其中有几行值得注意,如列表1所示。这里发生了什么?在高层次上,构建命令消耗你的源代码和你提供的元数据,以及它生成的一些文件,以创建。

  1. 一个源代码发布包:一个 Python 源码发布包,或称sdist ,是一个源代码的压缩存档文件,扩展名为.tgz
  2. 一个二进制发布包:一个 Python 内置发行包是一个二进制文件。目前内置发行包的标准是所谓的轮子或bdist_wheel ,一个扩展名为.whl 的文件。

清单 1.构建一个空的 Python 软件包的结果:

 ...
 Successfully installed setuptools-57.0.0 wheel-0.36.2                       

Setuptools 和 wheel 包被用于构建后端

源分发包是由 build_sdist 钩子 构建的

构建过程希望得到一个 README 文件,该文件有几种格式可供选择

构建过程希望得到软件包的名称和 URL

构建过程希望有一个软件包的作者或维护者

由于没有指定名称软件包被称为 UNKNOWN

源码分布是一个压缩的档案文件

二进制轮子发行包是由 build_wheel 钩子 构建的

二进制轮子发行包是一个 .whl 文件

因为你还没有提供任何元数据,所以构建过程会提醒你缺少一些重要的信息,比如README 文件、作者等等。添加这些信息将在本章后面介绍。

请注意,构建过程会安装setuptoolswheel 包。Setuptools(https://setuptools.readthedocs.io) 是一个库,在很长一段时间里,它是创建 Python 包的唯一方法之一。现在,Setuptools 是用于 Python 软件包构建的多种可用的构建后端之一。

定义:一个构建后端是一个Python对象,它提供了几个必要的和可选的钩子来实现打包行为。核心的构建后端接口在 PEP 517(https://www.python.org/dev/peps/pep-0517/#build-backend-interface) 中定义。

一个构建后端在构建过程中完成了创建软件包工件的后勤工作,即通过build_sdistbuild_wheel 钩子。Setuptools在build_wheel 步骤中使用wheel 包来构建轮子。当你没有指定后端时,build 工具默认使用Setuptools作为构建后端。

构建后台的存在可能会让你怀疑是否也会有构建前台。事实证明,你已经在使用一个构建前台了。build 工具就是一个构建前台。

定义: 构建前台是一个你运行的工具,用来启动从源代码构建软件包。构建前端提供一个用户界面,并通过钩子接口与构建后端集成。

简而言之,你使用一个构建前台工具,比如build 来触发一个构建后台,比如 Setuptools 来从你的源代码和元数据中创建软件包工件(图1)。


图 1.Python 构建系统由一个前端用户界面组成,它与后端集成以构建软件包工件。


因为构建过程会创建软件包工件,所以现在可以检查运行构建的效果。现在列出你的包的根目录的内容。你应该看到以下内容:

 $ ls -a1 $HOME/code/first-python-package/
 .
 ..
 .venv/
 UNKNOWN.egg-info/
 build/
 dist/
 pyproject.toml

UKNOWN.egg-info/build/ 目录是中间的工件。列出dist/ 目录的内容,你应该看到源代码和二进制轮子包文件:

 $ ls -a1 $HOME/code/first-python-package/dist/
 UNKNOWN-0.0.0-py3-none-any.whl
 UNKNOWN-0.0.0.tar.gz

其他构建系统工具

正如我前面提到的,对于构建前台和后台都存在其他的选择。有些软件包同时提供前台和后台,但我喜欢build 和Setuptools。

如果你想探索一些其他的构建工具,可以看看poetry(https://python-poetry.org/)和flit(https://flit.readthedocs.io)。每个构建系统都在配置的简易性、能力和用户界面之间做了不同的权衡。例如,flit和poetry是针对纯Python软件包的,而Setuptools可以支持其他语言的扩展。

你可以通过几个步骤切换到另一个构建系统:

  1. 安装新的构建前台包
  2. 更新pyproject.toml ,以指定新的构建后端和它的要求
  3. 将软件包的元数据转移到新的构建后端所期望的位置

记得build ,因为你没有指定,所以使用Setuptools作为后备构建后端。你可以通过在pyproject.toml 中添加列表2中的行来指定Setuptools作为你的软件包的构建后端。 这些行指定了以下内容。

  1. build-system- 本节描述了软件包的构建系统。
  2. requires- 这些是依赖关系的列表,以字符串的形式,必须安装这些依赖关系才能使构建系统工作。一个Setuptools构建系统需要setuptoolswheel ,正如你在本章前面看到的那样。
  3. build-backend- 这确定了构建后端对象的入口,使用点状路径作为字符串。Setuptools的构建后台对象可以在setuptools.build_meta

这些代表了你需要指定构建后端的完整配置。

清单 2.一个使用Setuptools的构建系统后端规范

 [build-system]                                         

打开一个新的 TOML 部分

以字符串形式列出软件包的名称

以字符串形式列出对象的带点路径 ❷以字符串形式列出对象的带点路径

一旦你添加了构建系统的信息,再次运行构建。输出结果应该没有变化:你只是把 Setuptools 锁定为显式后端,而不是让build 把它作为默认的。现在你已经掌握了 Python 软件包构建系统,你需要添加一些关于你的软件包的元数据。你可以这本书中读到所有的内容。