Nox在Python3.6与3.12切换时异常的原因及解决方法
问题原因分析与解决方法
原因解释
1. pyenv global 3.12 3.6时Nox找不到Python3.6的问题
pyenv设置多版本global时,python/pip等核心命令默认指向列表第一个版本(3.12)。Nox执行3.6测试时,若未明确指定对应版本的工具链,会优先调用默认的3.12相关命令,导致无法正确定位到3.6的独立解释器路径,进而触发“找不到解释器”的错误。
2. pyenv global 3.6 3.12时Python3.12测试pip报错的问题
此时系统默认pip是Python3.6的旧版本(pip 20.x及以下),而Python3.10+已移除pkgutil.ImpImporter属性。Nox运行3.12测试时,误调用了默认的3.6版本pip安装依赖,老版本pip的代码仍在引用已被移除的属性,因此触发AttributeError。
解决方法
方法1:给Nox明确指定对应版本的解释器绝对路径
在noxfile.py中,直接指定pyenv管理的对应版本解释器路径,避免工具链混用:
import nox import os # 替换为你实际的pyenv版本路径 PY36_PATH = f"{os.environ['HOME']}/.pyenv/versions/3.6.15/bin/python" PY312_PATH = f"{os.environ['HOME']}/.pyenv/versions/3.12.0/bin/python" @nox.session(python=[PY36_PATH, PY312_PATH]) def tests(session): session.install("-r", "requirements.txt") session.run("pytest")
方法2:避免pyenv多版本global设置,用局部/临时版本切换
取消pyenv global的多版本设置,改用项目局部版本或临时切换:
- 项目目录下设置默认版本:
pyenv local 3.12
- 运行不同版本测试时临时切换:
# 运行3.6测试 pyenv shell 3.6 && nox -s tests-3.6 && pyenv shell --unset # 运行3.12测试 pyenv shell 3.12 && nox -s tests-3.12 && pyenv shell --unset
也可以在noxfile.py中自动获取对应版本路径:
import nox import subprocess def get_pyenv_python(version): return subprocess.run( ["pyenv", "which", f"python{version}"], capture_output=True, text=True ).stdout.strip() @nox.session(python=[get_pyenv_python("3.6"), get_pyenv_python("3.12")]) def tests(session): session.install("-r", "requirements.txt") session.run("pytest")
方法3:临时升级Python3.6的pip到兼容版本(不推荐)
若必须保留多版本global,可升级3.6的pip到支持新版本Python的最后兼容版本(pip 21.3.1是支持Python3.6的最后版本):
pyenv shell 3.6 && pip install --upgrade pip==21.3.1
此方法仅作临时应急,仍存在潜在兼容性风险,优先推荐前两种方法。
内容的提问来源于stack exchange,提问作者ric81
相关产品推荐
相关产品推荐

