如何用pyproject.toml和setuptools管控Python包的许可与代码文件
解决方案
一、正确包含REUSE风格许可证文件(源码归档+Wheel包)
你之前的核心错误是license-files配置放错了位置,导致许可证文件无法被setuptools正确识别,按以下步骤修复:
1. 修正pyproject.toml配置
把原本在[metadata]下的license-files移到[tool.setuptools]区块,同时明确配置所有许可证文件:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "random_package" version = "0.1.0" # 指定主许可证,setuptools会自动将其放入wheel的dist-info目录 license = {file = "LICENSES/MAIN.txt"} [tool.setuptools] package-dir = {"" = "."} include-package-data = true # 配置所有需要包含的许可证文件,覆盖源码归档和wheel license-files = ["LICENSES/*.txt"] [tool.setuptools.packages.find] where = ["."] include = ["random_package*"]
2. 补充MANIFEST.in确保源码归档完整性
为了兼容旧版setuptools,在MANIFEST.in中添加许可证包含规则:
include LICENSES/*.txt
这样源码归档(tar.gz/zip)会完整包含LICENSES目录下的所有文件。
3. 让Wheel包包含完整LICENSES目录
如果希望整个LICENSES目录出现在Wheel根目录(同时主许可证仍会保留在dist-info目录),添加data-files配置:
[tool.setuptools.data-files] "" = ["LICENSES/*.txt"]
二、排除指定文件(submodule1/bar1.cpp)
需要分别针对源码归档和Wheel包配置排除规则:
1. Wheel包排除配置
在pyproject.toml中添加精确的排除规则,注意包的层级要匹配:
[tool.setuptools.exclude-package-data] "random_package.submodule1" = ["bar1.cpp"]
2. 源码归档排除配置
在MANIFEST.in中添加排除规则:
exclude random_package/submodule1/bar1.cpp
验证配置
执行python -m build后,分别检查:
- 解压源码归档,确认LICENSES目录完整,且无
random_package/submodule1/bar1.cpp - 用
unzip -l random_package-0.1.0-py3-none-any.whl查看Wheel内容,确认LICENSES文件存在,random_package/submodule1/下无bar1.cpp,同时dist-info目录中有MAIN.txt
额外说明
- 你期望许可证出现在Wheel包中完全合理,旧setup.py方案中单个License.txt会被自动放入dist-info,但REUSE风格的多许可证文件需要通过
license-files+data-files的组合配置实现。 - 之前
include-package-data=false时手动指定文件未生效,是因为手动指定需要配合package-data配置,而用exclude-package-data+include-package-data=true的方式更简洁可靠。
内容的提问来源于stack exchange,提问作者Silmathoron
相关产品推荐
相关产品推荐

