如何配置tox使用同一Python解释器兼容conda-forge与PyPI依赖
问题场景
我通过tox.ini执行pytest单元测试等流程,配置如下:
[tox] minversion = 3.24 envlist = default isolated_build = True [testenv] description = Invoke pytest to run automated tests deps = pytest coverage pytest-cov setenv = TOXINIDIR = {toxinidir} passenv = HOME SETUPTOOLS_* extras = testing commands = pip install --upgrade pip pip install -e . -r ./docs/requirements.txt pytest {posargs:tests}
在GitHub Actions CI工作流中,我会先安装Anaconda环境并部署关键依赖DIALS,步骤如下:
- name: Install Miniconda uses: conda-incubator/setup-miniconda@v2 with: miniconda-version: "latest" channels: conda-forge, defaults use-only-tar-bz2: true auto-update-conda: true auto-activate-base: true - name: Install DIALS environment run: | conda create -c conda-forge -y --name dials dials conda info $CONDA/bin/activate dials - name: Build with tox run: | tox -e build - name: Run tests with tox + pytest run: | tox
但运行时依赖DIALS的测试失败,提示ModuleNotFoundError: No module named 'dials',而pip安装的包可正常访问。原因是tox默认创建独立的虚拟环境,和conda的DIALS环境完全隔离,无法共享依赖。
解决方案
方案1:让tox复用已有的conda DIALS环境
通过指定tox使用conda环境中的Python解释器,让tox的测试环境复用已安装的DIALS依赖:
- 修改GitHub Actions中「Run tests with tox + pytest」步骤,激活conda环境后,将该环境的Python路径传给tox:
- name: Run tests with tox + pytest run: | source $CONDA/bin/activate dials tox --basepython=$(which python)
- (可选)如果需要固定Python路径,也可以在
tox.ini的[testenv]段添加basepython配置,但CI环境中路径可能不固定,推荐命令行传递:
[testenv] # 其他配置不变 basepython = /path/to/conda/dials/env/bin/python
方案2:用tox-conda插件让tox直接管理conda环境
通过tox-conda插件,让tox支持创建conda环境并安装conda源的依赖,同时兼容PyPI的pip依赖:
- 修改
tox.ini,添加tox-conda依赖并配置conda源的DIALS:
[tox] minversion = 3.24 envlist = default requires = tox-conda # 声明需要tox-conda插件 isolated_build = True [testenv] description = Invoke pytest to run automated tests conda_deps = conda-forge::dials # 从conda-forge安装DIALS deps = pytest coverage pytest-cov setenv = TOXINIDIR = {toxinidir} passenv = HOME SETUPTOOLS_* extras = testing commands = pip install --upgrade pip pip install -e . -r ./docs/requirements.txt pytest {posargs:tests}
- 简化GitHub Actions流程,无需手动创建DIALS环境,让tox自动处理:
- name: Install Miniconda uses: conda-incubator/setup-miniconda@v2 with: miniconda-version: "latest" channels: conda-forge, defaults use-only-tar-bz2: true auto-update-conda: true auto-activate-base: true - name: Install tox and tox-conda run: | pip install tox tox-conda - name: Build with tox run: | tox -e build - name: Run tests with tox + pytest run: | tox
原理说明
- tox默认使用venv/virtualenv创建独立虚拟环境,与conda环境完全隔离,因此无法访问conda安装的DIALS。
- 方案1通过指定basepython复用conda环境的解释器,让tox在该环境基础上安装pip依赖,实现两类依赖的共享。
- 方案2通过tox-conda扩展tox的环境创建逻辑,直接用conda创建环境,同时支持混合安装conda和pip依赖。
内容的提问来源于stack exchange,提问作者PrinceWalnut
相关产品推荐
相关产品推荐

