使用现代Python包装的setuptools插件可以进行自动化实验。
Python包装已经有了很大的发展。最新的("beta")使用一个文件,pyproject.toml ,来控制打包。
一个最小的pyproject.toml 可能看起来像这样。
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "cool_project"
version = "1.0.0"
项目部分
项目部分是关于 Python 项目本身的数据,包括像名字和版本这样的字段,这些是必须的。
其他字段也经常被使用,包括。
- description:一个单行的描述。
- readme:README 文件的位置。
- 作者:作者姓名和电子邮件。
- dependencies:这个项目所使用的其他软件包。
构建系统部分
尽管不一定要放在第一位,但构建系统通常放在最前面。这是因为它是最重要的部分。
build-backend键指向一个模块,该模块知道如何从项目中构建源发布和轮子。requires字段允许指定构建时的依赖性。
许多项目是用setuptools构建的。有一些新的替代品,如flit和hatch。
插件
build-system中的requires部分的一个好处是,它可以用来安装插件。尤其是setuptools包,它可以使用插件来修改其行为。
插件可以做的一件事是自动设置版本。这是一个流行的需求,因为版本管理往往是痛苦的。
片断
在继续之前,值得反思一下 "模仿 "的性质。X的模仿是X的一个实例,它夸大了某些方面,常常达到幽默的程度。
例如,"间谍电影的模仿 "是一部间谍电影,即使它是对这一类型的模仿。
对setuptools插件的戏仿
考虑到这一点,一个模仿setuptools的插件会是什么样子呢?根据上面的规则,它必须是一个插件。
这个名为onedotoh的插件,将版本设置为...为了成为一个插件,它首先必须是一个包。
一个包应该有一个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。这意味着函数guess_version将在setuptools准备最终确定发布选项时被调用。
guess_version的代码只有一行。
def guess_version(dist):
dist.metadata.version = "1.0.0"
版本为1.0.0
使用onedotoh是很微妙的。一个问题是把pyproject.toml 项目部分写成这样。
[project]
name = "a_pyproject"
version = "0.1.2"
pyproject.toml中的版本将覆盖插件中的版本。
明显的解决方案是删除版本字段。
[project]
name = "a_pyproject"
这以另一种方式失败了。如果没有项目部分的版本,该文件是无效的。名称将不会被使用。
正确的方法是如下。
[project]
name = "a_pyproject"
dynamic = ["version"]
这种方法明确地将版本字段声明为动态。
一个完整的例子会是这样的。
[build-system]
requires = [
"setuptools",
"onedotoh",
]
build-backend = "setuptools.build_meta"
[project]
name = "a_pyproject"
dynamic = ["version"]
最后,版本被自动设置为1.0.0。
总结
setuptools插件仍然可以用于现代的Python打包,只要相关的功能被明确声明为 "动态"。这使得一个领域充满了对自动化的进一步实验。