1 简介
在软件开发领域,项目构建方式的选择至关重要,可以直接影响到项目的可维护性、可扩展性以及与其他工具和环境的兼容性。近年来,随着Python生态系统的不断发展,一种新的项目构建方式逐渐崭露头角——使用pyproject.toml文件管理项目依赖和构建配置。相较于传统的setup.py方式,pyproject.toml具有诸多优势。
首先,pyproject.toml采用了更为现代化的格式,使用TOML(Tom’s Obvious, Minimal Language)语法,使得配置文件更易于阅读和编写。其次,pyproject.toml提供了更灵活的依赖管理机制,可以通过直接声明项目的依赖关系,而无需依赖于特定的构建工具或包管理器。此外,pyproject.toml还支持更丰富的构建配置选项,例如构建脚本、插件配置等,使得项目的构建过程更加可定制化和透明化。
在这篇博客中,我们将探讨如何如何通过简单的步骤将项目的构建方式从setup.py迁移到pyproject.toml,以实现更好的项目管理和更灵活的构建过程。
2 实现过程
2.1 迁移对项目属性信息的配置
将Paddle2ONNX的版本信息配置全部迁移到pyproject.toml中实现,setup.py仅用于执行CMake编译操作。因此在setup.py中删除除项目属性定义操作,然后在pyproject.toml中添加如下配置:
# 配置项目依赖项
requires = [
"setuptools>=42",
"wheel",
"cmake>=3.16",
"setuptools-scm"
]
build-backend = "setuptools.build_meta"
# 定义项目属性
[project]
name = "paddle2onnx"
description = "Export PaddlePaddle to ONNX"
readme = "README.md"
authors = [
{name = "paddle-infer", email = "paddle-infer@baidu.com"},
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
]
license = {text = "Apache License v2.0"}
requires-python = ">=3.8"
2.2 迁移对项目版本的配置
特别注意的是,Paddle2ONNX之前的构建方式参考ONNX来实现,版本控制这个环节是在setup.py中手动编写代码实现的,删除过后我们需要用现代的方法替换掉他:
# 定义项目属性
[project]
dynamic = ["version"]
[tool.setuptools.dynamic]
version = {file = "VERSION_NUMBER"}
[tool.setuptools_scm]
write_to = "paddle2onnx/version.py"
随后在paddle2onnx/init.py文件中删除掉对和git_version有关的变量,仅保留version,原因是git_version已经被整合到了version中
from paddle2onnx.utils import logging
from . import command
from .convert import dygraph2onnx
from .convert import program2onnx
from .version import version
__version__ = version
2.3 删除requirement.txt
我们希望实现通过pyproject.toml实现对整个依赖关系的清晰构建,因此删除了requirement.txt,改为在pyproject.toml中添加如下配置:
[project]
dependencies = [
"onnxruntime>=1.10.0",
]
当然,你也可以参考onnx的实现方式,用一种取巧的办法
[project]
dynamic = ["dependencies"]
[tool.setuptools.dynamic]
dependencies = {file = "requirements.txt"}
2.3 迁移命令行入口
删除setup.py对命令行入口的配置,在pyproject.toml中添加如下配置:
[project.scripts]
paddle2onnx = "paddle2onnx.command:main"
2.4 迁移find_packages操作
原setup.py中该操作通过**setuptools.find_packages()**来完成,迁移过后在pyproject.toml中添加如下配置:
[tool.setuptools.packages.find]
include = ["paddle2onnx*"]
2.5 其他的一些额外操作
参考了pybind给出的cmake_demo,额外添加了如下配置:
[tool.mypy]
files = "setup.py"
python_version = "3.8"
strict = true
show_error_codes = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true
2.6 添加MANIFEST.in
MANIFEST.in在编译时会拷贝所有的依赖文件,因此将编译需要依赖的文件写到这个文件中,具体如下:
recursive-include cmake *
recursive-include paddle2onnx *
recursive-include third_party *
recursive-include tools *
include LICENSE
include VERSION_NUMBER
include CMakeLists.txt
3 参考资料
提交一个PR总是要参考非常多的资料,我参考的主要资料如下:
- [Build][Update] Update the project’s build process to pyproject. by Zheng-Bicheng · Pull Request #1221 · PaddlePaddle/Paddle2ONNX
- GitHub - pybind/cmake_example: Example pybind11 module built with a CMake-based build system
- GitHub - onnx/onnx: Open standard for machine learning interoperability
- GitHub - jzhang533/randomfun
- Configuring setuptools using pyproject.toml files - setuptools 69.2.0.post20240313 documentation
- GitHub - pypa/setuptools_scm: the blessed package to manage your versions by scm tags
- 基于pyproject.toml的包管理(setuptools)
- Python - 如何打包并发布 Python 库到 PyPI