如何配置setuptools安装带git子模块依赖的私有Python包
解决方案
你原来的写法报错是因为install_requires默认只接收包名+版本约束的声明,直接填写本地路径不会被setuptools识别为依赖的安装地址。你可以用PEP 508规范的本地依赖声明实现需求,这是目前兼容性最好、无需额外工具的方案:
步骤1:修改setup.py的install_requires配置
首先确认你的子模块submodule-repo里的setup.py中定义的包名(即setup()函数的name参数值),假设子模块的包名是submodule,就将你原来的install_requires改成如下写法:
install_requires=[ "SQLAlchemy", "pandas", "submodule @ ./submodule-repo" ]
这里的@后面跟子模块相对于主包根目录的路径即可,setuptools和pip>=19.0版本都能直接识别该格式,安装主包时会自动从指定路径调用子模块的setup.py完成安装。
步骤2:告知用户克隆仓库时拉取子模块
因为子模块默认不会随主仓库一起克隆,你只需要在README里加一句克隆命令即可,不需要额外告知手动安装子模块:
git clone --recurse-submodules <你的主仓库git地址>
用户克隆后直接执行pip install .就能完成主包+子模块依赖的全自动安装。
兼容旧版pip的备选方案
如果需要兼容19.0以下版本的pip,可以配合dependency_links参数实现:
from setuptools import setup setup( # 其他原有配置不变 install_requires=[ "SQLAlchemy", "pandas", "submodule>=0.1.0" # 替换为你子模块的实际版本号 ], dependency_links=[ "file://./submodule-repo#egg=submodule-0.1.0" # 格式为file://路径#egg=包名-版本号 ] )
用户安装时执行pip install --process-dependency-links .即可生效。
注意事项
- 该方案完全保留子模块自身
setup.py的作用,不需要将子模块代码合并到主包的packages配置里 - 不需要搭建私有PyPI服务,也不需要额外的第三方工具
- 如果要分发源码包(sdist),打包时会自动包含子模块目录(只要你没有在
.gitignore里排除子模块路径),安装时同样会自动解析路径安装依赖
内容的提问来源于stack exchange,提问作者hyamanieu
相关产品推荐
相关产品推荐

