pyproject.toml 项目管理完全指南

pyproject.toml 是现代 Python 项目的标准配置中心:构建系统、项目元数据、依赖声明、工具配置与动态版本。本文系统讲解各核心区块的用法。

最佳实践
并发任务的多路径协同插画

直接回答:pyproject.toml 是 Python 项目的"宪法":PEP 518 引入、PEP 621 标准化,统一了构建配置、项目元数据与依赖声明,还把各工具(Ruff/Mypy/Pytest)的配置收拢一处——Poetry、PDM、Hatch、uv 都以它为中心。

为什么它取代了 setup.py

老时代的 setup.py 是可执行代码——想读个版本号都得先跑起来,安全隐患与复杂度齐飞;setup.cfg 静态但表达力弱。pyproject.toml 是纯声明式 TOML:静态可读、机器友好、标准统一,工具链各司其职而不互相发明格式。

核心区块解剖

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-awesome-lib"
version = "1.2.0"
description = "让某事更简单的库"
readme = "README.md"
requires-python = ">=3.10"
license = "MIT"  # 需支持 PEP 639 的构建后端
authors = [{ name = "张三", email = "zs@example.com" }]
dependencies = [
    "requests>=2.31",
    "pydantic>=2.0",
]

[project.optional-dependencies]
dev = ["pytest>=8", "ruff"]
docs = ["sphinx"]

[project.urls]
Homepage = "https://example.com"
Issues = "https://example.com/issues"

三个区块分工:[build-system] 告诉 pip 用什么构建你;[project] 是 PEP 621 标准元数据(任何工具都能读);[project.optional-dependencies] 定义可选依赖组(pip install pkg[dev])。

命令行入口

[project.scripts]
mycli = "mylib.cli:main"

安装后 mycli 命令直接可用——Python 包分发命令行工具的标准姿势。

工具配置收拢处

[tool.ruff]
line-length = 120

[tool.mypy]
strict = true

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.coverage.run]
source = ["src"]

[tool.*] 命名空间是各工具的认领区——项目根目录从此不再散落十几个 rc 文件。

动态版本

版本号不想写两处?让构建后端从代码里读:

[project]
# 合并到原 project 表,并删除原 version 字段;不要重复声明同名表
name = "my-awesome-lib"
dynamic = ["version"]

[tool.hatch.version]
path = "src/mylib/__about__.py"     # 文件里有 __version__ = "1.2.0"

或从 Git 标签派生(hatch-vcs / setuptools-scm):配置相应插件和构建后,Git 标签可作为版本来源;打标签本身不会发布包,彻底消灭"忘了改版本号"。

依赖声明的分寸

库与应用不同:库的依赖约束要宽(>=2.0,给用户留兼容空间),精确锁定交给应用的 lock 文件;应用可以更严,且应配 lock(uv.lock/pdm.lock/poetry.lock)保证部署可复现。

常见问题(FAQ)

Q:pyproject.toml 能完全替代 requirements.txt 吗?
A:定位不同:pyproject 是依赖声明(范围约束),requirements 可写版本范围或 pin,锁文件记录解析结果。应用部署仍需 lock 文件;requirements.txt 可以作为由 pyproject 导出的产物存在。

Q:构建后端选哪个?
A:Hatchling(Hatch 后端,简洁现代)、setuptools(老牌全能)、pdm-backend、flit-core(纯库极简)都合规。新项目推荐 hatchling。

Q:src 布局还要吗?
A:要。src/mypkg/ 布局防止"在项目根目录碰巧 import 成功、发布后却缺文件"的经典事故,并按构建后端配置包发现;不存在跨后端统一的 packages 键。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台