Python setup.cfg中如何将Git子模块添加为package_data?
问题场景
我正在开发一个Python包,在setup.cfg中配置package_data如下:
include_package_data = True [options.package_data] mypymodule = dir1/*/*, dir2/*/*
dir1和dir2均位于包的mypymodule源码目录下,包的构建、安装与使用均无问题。
目前遇到的问题:dir1和dir2都包含子目录及文件,希望这些内容都能被包含到安装文件中以便运行时访问。其中dir1(仓库普通目录)的所有子目录都能正确安装,但dir2(Git子模块目录)仅根目录的文件被包含,子目录全部被忽略,无法访问。
已尝试修改setup.cfg中的通配符但未解决,期望普通目录与Git子模块目录能被同等处理。请问遗漏了什么?Python包的setup.cfg在将Git子模块作为package_data时存在限制吗?
核心原因
Git子模块本身是独立的Git仓库,默认情况下,Python打包工具(如setuptools)处理package_data通配符时,不会递归进入Git子模块的内部目录——因为子模块在主仓库中是以Git链接对象形式存在,而非普通文件系统目录结构,打包工具无法识别其内部层级。
另外,include_package_data = True依赖MANIFEST.in文件(若存在),如果该文件未明确包含子模块内容,也会导致子目录被忽略。
解决办法
1. 修改MANIFEST.in显式包含子模块内容
在项目根目录创建或修改MANIFEST.in,添加:
recursive-include mypymodule/dir2 *
这会强制打包工具递归包含dir2下所有文件和子目录,不受Git子模块属性影响。
2. 调整setup.cfg的package_data配置
使用setuptools支持的递归通配符**(需较新版本setuptools),匹配任意层级的子目录和文件:
[options.package_data] mypymodule = dir1/*/*, dir2/**/*
3. 确保子模块已完全初始化
打包前执行以下命令,拉取子模块的全部内容:
git submodule update --init --recursive
若子模块未初始化,打包工具看到的只是空目录或Git链接,无法包含子目录内容。
4. 避免依赖include_package_data的隐式处理
使用Git子模块时,建议显式配置package_data和MANIFEST.in,而非依赖include_package_data = True的自动识别——自动识别可能会忽略Git子模块的内部结构。
补充说明
setuptools本身没有针对Git子模块的特殊限制,问题本质是Git子模块的文件系统表现与普通目录不同:主仓库仅存储子模块引用,实际内容需单独拉取。打包工具默认不会跨越Git子模块边界,因此需要显式配置强制包含其内容。
内容的提问来源于stack exchange,提问作者ysba

