使用tox或pip时通过requirements.txt安装传递依赖的方法咨询
你遇到的报错核心原因是:requirements.txt不属于Python包的标准元数据,pip仅在你手动指定-r <requirements文件路径>参数时才会读取该文件的内容。当你通过路径安装本地包(比如requirements里写../module_b)时,pip不会主动读取该包目录下的requirements.txt,只会读取该包内置的打包配置文件(pyproject.toml/setup.py/setup.cfg)中声明的依赖,因此不会自动安装module_c。
你之前在module_b目录下执行pip install -r requirements.txt可以正常安装,是因为你主动指定了读取module_b的requirements.txt,属于手动触发的依赖安装,和pip安装包时的自动依赖解析逻辑无关。
方案1:添加包标准元数据(推荐)
这是最符合Python打包规范的方案,配置后不管是用pip直接安装还是通过tox运行,都能自动解析完整依赖链。
给每个模块根目录新增pyproject.toml,声明自身的依赖信息,以module_b为例:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "module_b" version = "0.1.0" # 声明依赖的module_c路径,三个模块平级的情况下直接写相对路径即可 dependencies = [ "module_c @ file://../module_c" ]
module_a的pyproject.toml只需要声明依赖module_b即可:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "module_a" version = "0.1.0" dependencies = [ "module_b @ file://../module_b" ]
配置完成后,你可以完全去掉各模块的requirements.txt,直接把tox.ini的deps改成安装当前模块即可:
[testenv] deps = .[test] # 如果你有测试依赖也可以写到optional-dependencies里 commands = pytest --cov {envsitepackagesdir}/module_a
方案2:链式引用requirements.txt(无需修改打包逻辑)
如果不想调整现有打包配置,可以通过requirements文件嵌套引用的方式实现依赖自动安装:
修改module_b的requirements.txt,新增对module_c的requirements的引用:
# module_b/requirements.txt -r ../module_c/requirements.txt ../module_c
module_a的requirements.txt保持仅引用module_b即可:
# module_a/requirements.txt -r ../module_b/requirements.txt ../module_b
这种方式下pip执行-r module_a/requirements.txt时,会顺着-r的引用链自动读取所有依赖的requirements文件,完成全量安装,tox配置无需做任何修改。
方案3:仅调整tox配置适配现有逻辑
如果不想修改任何requirements或打包文件,可以调整tox的安装命令,先切换到对应依赖目录完成安装再跑测试:
[testenv] # 去掉原有deps配置,改用pre命令按顺序安装依赖 commands_pre = # 先装module_c cd {toxinidir}/../module_c && pip install . # 再装module_b cd {toxinidir}/../module_b && pip install . commands = pytest --cov {envsitepackagesdir}/module_a
内容的提问来源于stack exchange,提问作者wagnermps

