如何一起使用现代 Python 打包和 setuptools 插件

将 setuptools 插件与现代 Python 打包结合使用可以进行自动化实验。
2 位读者喜欢这篇文章。
How to write a web service using Python Flask

Yuko Honda 在 Flickr 上。CC BY-SA 2.0

Python 打包已经发展了很多。最新的(“beta”)使用一个文件 pyproject.toml 来控制包。

一个最小的 pyproject.toml 可能看起来像这样

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "cool_project"
version = "1.0.0"

project 部分

project 部分是关于 Python 项目自身的数据,包括诸如 nameversion 等字段,这些字段是必需的。

其他字段也经常使用,包括

  • description:一行描述。
  • readme:README 文件的位置。
  • authors:作者姓名和电子邮件。
  • dependencies:此项目使用的其他包。

build-system 部分

虽然不一定必须是第一个,但 build-system 通常位于顶部。这是因为它最重要。

build-backend 键指向一个模块,该模块知道如何从项目构建源发行版和 wheel 文件。requires 字段允许指定构建时依赖项。

许多项目都是用 setuptools 构建的。还有一些新的替代方案,例如 flithatch

插件

build-systemrequires 部分的一个好处是它可以用来安装插件。特别是 setuptools 包,可以使用插件来修改其行为。

插件可以做的一件事是自动设置版本。这是一个普遍的需求,因为版本管理通常很麻烦。

过渡

在继续之前,值得反思一下“模仿”的本质。X 的模仿X 的一个实例,它夸大了某些方面,通常达到了幽默的程度。

例如,“间谍电影的模仿”一部间谍电影,即使它戏仿了这种类型。

setuptools 插件的模仿

考虑到这一点,setuptools 插件的模仿会是什么样子?根据上面的规则,它必须是一个插件。

这个插件名为 onedotoh,它将版本设置为... 1.0.0。为了成为一个插件,它首先必须是一个包。

一个包应该有一个 pyproject.toml

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "onedotoh"
version = "1.0.0"

[project.entry-points."setuptools.finalize_distribution_options"]
setuptools_scm = "onedotoh:guess_version"

有一个新的部分:project.entry-points。这意味着当 setuptools 准备好最终确定分发选项时,将调用函数 guess_version

guess_version 的代码只有一行

def guess_version(dist):
    dist.metadata.version = "1.0.0"

版本设置为 1.0.0

使用 onedotoh 很微妙。一个问题是编写 pyproject.tomlproject 部分,使其看起来像这样

[project]
name = "a_pyproject"
version = "0.1.2"

pyproject.toml 中的 version覆盖来自插件的版本。

显而易见的解决方案是删除 version 字段

[project]
name = "a_pyproject"

但这会以不同的方式失败。如果没有 project 部分中的 version,该文件将无效。name 将不会被使用。

正确的方法如下

[project]
name = "a_pyproject"
dynamic = ["version"]

这种方法明确地将 version 字段声明为动态的。

一个完整的例子看起来像这样

[build-system]
requires = [
    "setuptools",
    "onedotoh",
]
build-backend = "setuptools.build_meta"

[project]
name = "a_pyproject"
dynamic = ["version"]

最终,版本被自动设置为 1.0.0

总结

setuptools 插件仍然可以与现代 Python 打包一起使用,只要相关功能被明确声明为“动态”。这使得该领域非常适合进一步的自动化实验。

例如,除了从外部元数据猜测版本之外,如果它也使用 git remote URL 来猜测名称,会怎么样呢?

标签
Moshe sitting down, head slightly to the side. His t-shirt has Guardians of the Galaxy silhoutes against a background of sound visualization bars.
自 1998 年以来,Moshe 一直参与 Linux 社区,帮助举办 Linux “安装派对”。他自 1999 年开始编写 Python 程序,并为核心 Python 解释器做出了贡献。Moshe 在 DevOps/SRE 这些术语出现之前就已经是 DevOps/SRE,他非常关心软件可靠性、构建可重现性以及其他此类事情。

评论已关闭。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.