pyproject.toml 是 Python 打包事实标准,需在[build-system]中声明 build-backend="setuptools.build_meta" 和 requires=["setuptools>=61.0","wheel"],并用[project]替代 setup.py 配置元数据。

PyProject.toml 已成为 Python 打包事实标准,setuptools 本身也已全面转向基于 pyproject.toml 的配置方式;直接写 setup.py 不仅过时,还会在 pip ≥23.1+ 和最新版本的 build 工具中触发警告甚至失败。
pyproject.toml 中必须声明 build-backend
很多项目卡在第一步:运行 python -m build 报错 ModuleNotFoundError: No module named 'setuptools.build_meta' 或提示 “no build backend specified”。这是因为缺失 build-backend 声明。
- 必须在
[build-system]段落中显式指定build-backend = "setuptools.build_meta" -
requires至少包含"setuptools>=61.0"(支持 PEP 621)和"wheel"(生成 .whl 文件必需) - 若用
setuptools_scm自动管理版本,需额外加入"setuptools-scm[toml]>=8.0"到requires
[build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta"
用 PEP 621 标准化项目元数据(替代 setup.py)
不再需要 setup.py 或 setup.cfg。所有项目信息统一写入 [project] 段落,这是 setuptools 61.0+ 原生支持的现代写法。
-
name、version、description、readme、requires-python是必填项 -
dependencies替代install_requires,格式为字符串列表,支持 PEP 508 表达式(如"requests>=2.25; platform_system != 'Windows'") -
optional-dependencies对应extras_require,键名即 extra 名(如dev),值为依赖列表 - 若想自动从
__version__或 Git tag 提取版本,请启用setuptools_scm并删掉version字段 —— 否则会冲突
[project] name = "mylib" version = "0.1.0" description = "A sample package" readme = "README.md" requires-python = ">=3.8" dependencies = ["requests>=2.25"] [project.optional-dependencies] dev = ["pytest>=7.0", "black"]
动态版本号:setuptools_scm 配置要点
手动维护 version 容易出错。用 setuptools_scm 可从 Git commit / tag 自动生成,但配置稍有不慎就失效。
立即学习“Python免费学习笔记(深入)”;
- 先确保项目根目录是 Git 仓库(含
.git/),且至少有一个带语义化标签的 commit(如v0.1.0) - 在
[build-system]的requires中加入"setuptools-scm[toml]>=8.0" - 删除
[project].version字段,否则setuptools_scm不生效 - 可选:添加
[tool.setuptools_scm]段落自定义行为,例如忽略未提交变更:fallback_version = "0.0.0",或禁用本地节点标记:local_scheme = "no-local-version"
打包命令与常见陷阱
执行 python -m build 默认生成 sdist(.tar.gz)和 wheel(.whl);但实际 CI/CD 中常需控制输出类型或跳过某些步骤。
- 只构建 wheel:
python -m build --wheel;只构建源码包:python -m build --sdist - 若报错
error: invalid command 'bdist_wheel',说明wheel未列在build-system.requires中 - 打包后验证:用
twine check dist/*检查包元数据是否合规(注意不是所有警告都致命,但InvalidDistribution类错误必须修复) - 上传前务必确认
project.urls、project.authors等字段已填写,否则 PyPI 会拒绝无描述或无作者的包
最常被忽略的是 Git 状态:setuptools_scm 要求工作区干净或显式允许脏提交(dirty = true),否则可能静默回退到 fallback 版本;还有人把 pyproject.toml 放错位置——它必须在项目根目录,且不能被 MANIFEST.in 排除(虽然现在多数情况不再需要 MANIFEST.in)。


















