pyproject.toml 的历史背景和原理

历史背景

PEP 517 和 PEP 518 是 pyproject.toml 诞生的关键推动力:

  1. PEP 518 (2016) :提出了 pyproject.toml 文件格式,用于指定构建系统要求
  2. PEP 517 (2017):定义了构建前端和后端的接口标准,使构建过程标准化
  3. 传统问题:之前依赖 setup.py 和 setuptools,缺乏标准化,构建环境不一致

设计原理

  1. 声明式配置:使用 TOML 格式,更易于机器解析和人类阅读
  2. 构建系统隔离:明确指定构建依赖,避免环境污染
  3. 可扩展性:支持多种构建后端(setuptools, poetry, flit, hatch等)
  4. 元数据统一:包含项目元数据、构建配置、工具配置等

setup.py vs pyproject.toml 调用方法差异

setup.py(传统方式)

python 复制代码
# setup.py
from setuptools import setup, find_packages

setup(
    name="my-package",
    version="1.0.0",
    packages=find_packages(),
    install_requires=[
        "requests>=2.25.0",
        "numpy>=1.19.0"
    ],
    extras_require={
        "dev": ["pytest", "black"],
        "docs": ["sphinx"]
    },
    entry_points={
        "console_scripts": [
            "my-cli=my_package.cli:main"
        ]
    }
)

构建命令

bash 复制代码
# 源码安装
python setup.py install

# 开发模式
python setup.py develop

# 构建分发包
python setup.py sdist bdist_wheel

pyproject.toml(现代方式)

toml 复制代码
# pyproject.toml
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "my-package"
version = "1.0.0"
dependencies = [
    "requests>=2.25.0",
    "numpy>=1.19.0"
]

[project.optional-dependencies]
dev = ["pytest", "black"]
docs = ["sphinx"]

[project.scripts]
my-cli = "my_package.cli:main"

[tool.setuptools]
packages = {find = {}}

构建命令

bash 复制代码
# 使用 PEP 517 兼容工具构建
pip install -e .  # 开发模式
pip install .     # 安装
python -m build   # 构建分发包

# 或者使用特定后端
python -m setuptools.build_meta

关键差异对比

特性 setup.py pyproject.toml
格式 Python 代码 TOML 声明式配置
构建依赖 隐式依赖 setuptools 显式声明在 [build-system]
环境隔离 差,依赖全局环境 好,明确构建环境
可重现性
安全性 执行任意代码 只读配置
元数据 代码中定义 声明式配置
扩展性 有限 支持多种后端

RPM 包管理版本支持情况

RPM 版本支持时间线

RPM 版本 发布时间 pyproject.toml 支持 关键特性
RPM 4.11 2015 ❌ 不支持 传统 setup.py only
RPM 4.12 2017 ⚠️ 有限支持 初步 PEP 517 实验
RPM 4.13 2018 ⚠️ 基本支持 支持 %pyproject_buildrequires
RPM 4.14 2019 ✅ 基本完整 支持 %pyproject_wheel
RPM 4.15 2020 ✅ 完整支持 完整 PEP 517/518 支持
RPM 4.16+ 2021+ ✅ 成熟支持 优化构建流程

不同 RPM 版本的 spec 文件写法

RPM 4.11-4.12(传统方式)
spec 复制代码
%build
python setup.py build

%install
python setup.py install --root=%{buildroot}
RPM 4.13-4.14(过渡期)
spec 复制代码
%build
# 手动处理 pyproject.toml
python -m pip wheel --no-deps --no-build-isolation -w dist .

%install
python -m pip install --no-deps --no-index --find-links=dist \
    --prefix=%{buildroot}%{_prefix} .
RPM 4.15+(现代方式)
spec 复制代码
%build
%pyproject_wheel

%install
%pyproject_install

针对低版本 RPM 4.14 的解决方案

spec 复制代码
# 对于 RPM 4.14,需要手动实现 PEP 517 构建
%build
export PIP_NO_BUILD_ISOLATION=0
export PYTHONPATH=%{_builddir}/%{name}-%{version}

# 手动构建 wheel
python -m pip wheel --no-deps --no-build-isolation --wheel-dir=dist .

%install
rm -rf %{buildroot}
mkdir -p %{buildroot}%{python3_sitearch}

# 手动安装 wheel
WHEEL_FILE=$(ls dist/*.whl | head -1)
python -m pip install --no-index --no-deps --ignore-installed \
    --target=%{buildroot}%{python3_sitearch} \
    --no-build-isolation \
    ${WHEEL_FILE}

构建后端支持矩阵

构建后端 RPM 4.14 支持 RPM 4.15+ 支持 说明
setuptools ✅ 通过 pip wheel ✅ 原生支持 最常用
poetry ⚠️ 需要 poetry-core ✅ 完整支持 需要额外依赖
flit ⚠️ 需要手动处理 ✅ 完整支持 简单项目
hatch ⚠️ 有限支持 ✅ 完整支持 新兴工具
pdm ❌ 不支持 ⚠️ 有限支持 较新工具

兼容性建议

  1. 对于低版本 RPM :使用 pip wheel 手动构建
  2. 检查构建后端:确保构建依赖在 RPM 环境中可用
  3. 测试验证:在不同 RPM 版本上测试构建过程
  4. 回退方案:准备 setup.py 作为备选(如果需要支持很旧的系统)

现状总结

  • RPM 4.15+ :推荐使用 %pyproject_wheel%pyproject_install
  • RPM 4.14:需要手动处理,但可以正常工作
  • RPM 4.13 及以下:建议升级或使用传统 setup.py 方式

现在大多数现代 Linux 发行版(RHEL 8+、Fedora、openEuler 等)都使用 RPM 4.14+,可以较好地支持 pyproject.toml 构建。

相关推荐
蒋星熠2 小时前
中间件架构设计与实践:构建高性能分布式系统的核心基石
开发语言·数据库·分布式·python·中间件·性能优化·硬件工程
海天一色y5 小时前
Pycharm(二十一)递归删除文件夹
ide·python·pycharm
乔巴先生2410 小时前
LLMCompiler:基于LangGraph的并行化Agent架构高效实现
人工智能·python·langchain·人机交互
张子夜 iiii11 小时前
实战项目-----Python+OpenCV 实现对视频的椒盐噪声注入与实时平滑还原”
开发语言·python·opencv·计算机视觉
困鲲鲲12 小时前
Flask 核心基础:从 路由装饰器 到 __name__ 变量 的底层逻辑解析
python·flask
njxiejing12 小时前
Python NumPy安装、导入与入门
开发语言·python·numpy
Rhys..13 小时前
Python&Flask 使用 DBUtils 创建通用连接池
开发语言·python·mysql
Just_Paranoid13 小时前
【Python Tkinter】图形用户界面(GUI)开发及打包EXE指南
python·gui·tkinter·pyinstaller
小宁爱Python13 小时前
Django 基础入门:命令、结构与核心配置全解析
后端·python·django