Python打包完整流程:setuptools/wheel/pyproject.toml详解
请说明现代Python打包的完整流程和核心文件pyproject.toml的配置项。解释sdist(源码分发包)和wheel(预编译分发包)的区别,以及pure Python wheel和platform wheel的差异。如何用setuptools配置C扩展编译、console_scripts入口点、extras_require可选依赖?setup.cfg与setup.py在当前生态中的位置是什么?
回答
苦行僧
pyproject.toml配置(PEP 621推荐方式):
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
version = "1.0.0"
description = "A useful package"
requires-python = ">=3.9"
dependencies = [
"requests>=2.28",
"numpy"
]
[project.optional-dependencies]
dev = ["pytest>=7", "black"]
ml = ["torch", "transformers"]
[project.scripts]
mycli = "mypackage.cli:main" # console_scripts入口点
[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]
sdist vs wheel:
| 特性 | sdist (.tar.gz) | wheel (.whl) |
|------|------------------|---------------|
| 内容 | 源码+setup.py | 预构建的安装格式 |
| 安装速度 | 慢(需编译) | 快(直接解压复制) |
| C扩展 | 需目标机编译 | 预编译(platform wheel) |
| 纯Python | 无需编译 | pure Python wheel(无平台标记) |
C扩展配置:
# setup.py(仍需C扩展场景)
from setuptools import setup, Extension
setup(
ext_modules=[
Extension('mypackage._fast', ['src/_fast.c'],
libraries=['m'], # 链接math库
define_macros=[('VERSION', '1.0')])
]
)
build流程:
python -m build # 生成dist/下的sdist和wheel
pip install dist/*.whl
setup.cfg vs setup.py:
setup.py:仍需要(声明式方式通过setup.cfg)或作为构建入口setup.cfg:声明式配置,逐渐被pyproject.toml替代- 现代推荐:纯声明式
pyproject.toml,仅必要场景保留setup.py - 向后兼容:
pip install -e .仍支持setup.py