如何在pyproject.toml中为Python子包设置同版本动态依赖?
解决方案
针对你的命名空间包版本依赖需求,有几种可行的方式在pyproject.toml中动态注入统一版本号:
方法一:结合setuptools动态配置(推荐,无需预生成文件)
这种方式利用setuptools的动态元数据能力,直接从VERSION文件读取版本并生成依赖:
- 根目录下保留
VERSION文件(内容为纯版本号,比如1.0.0)。 - 主包
aabbcc的pyproject.toml配置:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "aabbcc" dynamic = ["version", "dependencies", "optional-dependencies"]
- 主包根目录创建
setup.py,读取VERSION并设置依赖:
from setuptools import setup with open("VERSION", "r") as f: pkg_version = f.read().strip() setup( version=pkg_version, install_requires=[ f"aabbcc-core=={pkg_version}", ], extras_require={ "aws": [ f"aabbcc-aws=={pkg_version}", ], }, )
- 子包
aabbcc-aws的pyproject.toml同样配置动态元数据:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "aabbcc-aws" dynamic = ["version", "dependencies"]
aabbcc-aws目录下创建setup.py:
from setuptools import setup # 假设VERSION文件在项目根目录,根据实际路径调整 with open("../VERSION", "r") as f: pkg_version = f.read().strip() setup( version=pkg_version, install_requires=[ f"aabbcc-core=={pkg_version}", ], )
方法二:预生成pyproject.toml(适合纯静态配置场景)
通过脚本读取VERSION文件,替换模板中的占位符生成最终的pyproject.toml:
- 创建
pyproject.toml.in模板文件(主包用):
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "aabbcc" version = "{{VERSION}}" dependencies = [ "aabbcc-core=={{VERSION}}", ] [project.optional-dependencies] aws = [ "aabbcc-aws=={{VERSION}}", ]
- 编写版本替换脚本
update_version.py:
import tomli import tomli_w # 读取版本号 with open("VERSION", "r") as f: pkg_version = f.read().strip() # 读取模板 with open("pyproject.toml.in", "rb") as f: config = tomli.load(f) # 替换所有占位符 config["project"]["version"] = pkg_version config["project"]["dependencies"] = [dep.replace("{{VERSION}}", pkg_version) for dep in config["project"]["dependencies"]] config["project"]["optional-dependencies"]["aws"] = [dep.replace("{{VERSION}}", pkg_version) for dep in config["project"]["optional-dependencies"]["aws"]] # 生成最终的pyproject.toml with open("pyproject.toml", "wb") as f: tomli_w.dump(config, f)
- 打包前先运行脚本:
python update_version.py,再执行python -m build。 - 子包
aabbcc-aws可以用同样的模板+脚本方式,调整路径读取根目录的VERSION文件。
方法三:使用setuptools-scm自动管理版本
如果你的项目用Git做版本控制,setuptools-scm可以自动从VERSION文件或Git标签读取版本,同时支持动态依赖:
- 安装依赖:
pip install setuptools-scm[toml] - 主包
pyproject.toml配置:
[build-system] requires = ["setuptools>=61.0", "setuptools-scm[toml]>=7.0"] build-backend = "setuptools.build_meta" [project] name = "aabbcc" dynamic = ["version", "dependencies", "optional-dependencies"] [tool.setuptools-scm] version_file = "VERSION" # 指定读取VERSION文件
- 主包的
setup.py内容和方法一一致,读取版本并设置依赖。 - 子包
aabbcc-aws的pyproject.toml配置:
[build-system] requires = ["setuptools>=61.0", "setuptools-scm[toml]>=7.0"] build-backend = "setuptools.build_meta" [project] name = "aabbcc-aws" dynamic = ["version", "dependencies"] [tool.setuptools-scm] version_file = "../VERSION" root = ".." # 指向项目根目录,确保读取正确的版本文件
内容的提问来源于stack exchange,提问作者Aleksandr Krymskiy
相关产品推荐
相关产品推荐

