pyproject.toml 中 [build-system] 段必须包含 requires 和 build-backend:requires 列构建依赖(如 ["setuptools>=45", "wheel"]),build-backend 指定后端(如 "setuptools.build_meta"),缺一则 pip 或 build 会报错或降级失败。

pyproject.toml 里 build-system 必须写什么?
不写 build-system 段,现代 Python 构建工具(如 pip、build)会直接报错或降级到旧式隐式构建逻辑,导致依赖不一致或安装失败。
最小合法配置必须包含 requires 和 build-backend:
[build-system] requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta"
-
requires列的是构建时依赖(不是运行时依赖),必须是 PEP 517 兼容的包;setuptools版本太低会导致pyproject.toml中的某些字段(如dynamic)被忽略 -
build-backend值必须对应已安装的 backend 模块入口点,常见值有:"setuptools.build_meta"、"hatchling.build"、"poetry.core.masonry.api";拼错或未安装对应包会触发ModuleNotFoundError - 不要把
pip或python放进requires—— 它们是构建环境前提,不是构建依赖
如何用 tool.setuptools 替代 setup.py?
setup.py 已被标记为 deprecated,所有配置应迁移到 pyproject.toml 的 tool.setuptools 段。迁移不是简单复制粘贴,字段语义和默认行为有差异。
例如定义包名、版本、入口点:
立即学习“Python免费学习笔记(深入)”;
[project]
name = "mylib"
version = "0.1.0"
dependencies = ["requests>=2.25.0"]
<p>[project.entry-points."console_scripts"]
mycmd = "mylib.cli:main"</p><p>[tool.setuptools]</p><h1>启用自动发现包(替代 find_packages())</h1><p>py-modules = []
packages = {find = {where = ["src"], include = ["mylib*"]}}</p><h1>动态版本(替代 setup.py 中的 scm 版本生成)</h1><p>dynamic = ["version"]</p><p>[tool.setuptools.dynamic.version]
attr = "mylib.<strong>version</strong>"-
packages和py-modules互斥;用find时注意where路径是相对于项目根目录,不是pyproject.toml所在路径 -
dynamic.version需配合setuptools_scm使用,且要求 Git 仓库存在有效 tag;否则构建会失败并提示Version scheme 'guess-next-dev' did not generate a version -
project.dependencies是 PEP 621 标准字段,优先级高于tool.setuptools.install_requires;两者共存时后者会被忽略
为什么 tool.poetry 不能和 tool.setuptools 混用?
Poetry 不是 PEP 517 构建后端,它只读取自己的 tool.poetry 段,并忽略 tool.setuptools 或 project。混用会导致构建行为不可预测:比如 pip install . 走 setuptools,poetry build 走 Poetry,产出的 wheel 元数据可能不一致。
- 若用 Poetry 管理依赖和发布,
build-backend应设为"poetry.core.masonry.api",且requires必须含"poetry-core>=1.0.0" - Poetry 不支持
project.dependencies字段,必须用tool.poetry.dependencies;但该段不参与 PEP 517 构建,仅用于poetry install或poetry export - 想兼顾
pip install .和poetry add?别这么做。选一个构建系统,统一维护。Poetry 用户应禁用setup.py和tool.setuptools,避免干扰
虚拟环境里 pip install . 为什么还是装错依赖?
根本原因常是 build-system.requires 与 project.dependencies 混淆,或构建缓存未清理。
-
build-system.requires只影响构建过程本身(如生成 wheel),不影响最终安装的包依赖;真正决定用户pip install后获得哪些依赖的是project.dependencies(PEP 621)或tool.setuptools.install_requires(旧式) - 执行
pip install .时,pip 会先调用构建后端生成 wheel,再安装 wheel —— 如果之前构建过且 wheel 缓存未失效,pip 可能复用旧 wheel,导致新改的dependencies不生效。解决方法是加--force-reinstall --no-deps或删掉./dist/目录再试 - 检查最终安装结果是否正确:运行
pip show mylib,看Requires:行是否匹配project.dependencies内容;不匹配说明构建阶段没读取到最新配置
最易被忽略的是:pyproject.toml 的语法错误(比如多了一个逗号、引号不闭合)不会在编辑时报警,而是在构建时静默失败回退到旧逻辑,建议用 tomllib(Python 3.11+)或 tomli 手动验证文件格式。


















