-
-
Notifications
You must be signed in to change notification settings - Fork 539
Description
Issue
Environments defined with a missing interpreter and whose set_env is substituting values from the root testenv raise an exception even if skip_missing_interpreter == True
ROOT: HandledError| replace failed in py312.set_env with RuntimeError("failed to find interpreter for Builtin discover of python_spec='py312'")
Environment
Running Python 3.10.12 from virtual env with Tox 4.27.0 installed on Ubuntu 22.04.5 LTS
Output of pip list
of the host Python, where tox
is installed
$pip3 -V
pip 24.0 from /home/steve/PycharmProjects/tox4-test/venv-3.10/lib/python3.10/site-packages/pip (python 3.10)
$pip3 list
Package Version
----------------------- -----------
annotated-types 0.7.0
astroid 3.3.11
backports.tarfile 1.2.0
betterproto 2.0.0b6
build 1.2.2.post1
cachetools 6.1.0
certifi 2024.2.2
cffi 1.16.0
chardet 5.2.0
charset-normalizer 3.3.2
colorama 0.4.6
cryptography 44.0.3
dill 0.4.0
distlib 0.3.8
dnspython 2.7.0
docutils 0.21.2
dumb-pypi 1.15.0
email_validator 2.2.0
exceptiongroup 1.2.1
filelock 3.18.0
git-filter-repo 2.47.0
grpclib 0.4.8
h2 4.2.0
hpack 4.1.0
hyperframe 6.1.0
id 1.5.0
idna 3.7
importlib_metadata 8.7.0
importlib-resources 5.13.0
iniconfig 2.0.0
isort 6.0.1
jaraco.classes 3.4.0
jaraco.context 5.3.0
jaraco.functools 4.0.1
jeepney 0.8.0
Jinja2 3.1.4
keyring 25.2.1
markdown-it-py 3.0.0
MarkupSafe 2.1.5
mccabe 0.7.0
mdurl 0.1.2
more-itertools 10.2.0
multidict 6.6.3
nh3 0.2.17
packaging 25.0
pbr 6.0.0
pip 24.0
pkg_about 1.3.6
pkginfo 1.10.0
platformdirs 4.3.8
pluggy 1.5.0
py 1.11.0
pyasn1 0.6.1
pycparser 2.22
pydantic 2.11.7
pydantic_core 2.33.2
Pygments 2.18.0
PyJWT 2.10.1
pylint 3.3.7
pyOpenSSL 25.1.0
pyproject-api 1.9.1
pyproject_hooks 1.2.0
pytest 8.2.1
pytest-pylint 0.21.0
python-dateutil 2.9.0.post0
PyYAML 6.0.1
readme_renderer 43.0
requests 2.32.3
requests-toolbelt 1.0.0
rfc3161-client 1.0.3
rfc3986 2.0.0
rfc8785 0.1.4
rich 13.7.1
SecretStorage 3.3.3
securesystemslib 1.3.0
setuptools 80.9.0
sigstore 3.6.4
sigstore-protobuf-specs 0.3.2
sigstore-rekor-types 0.0.18
six 1.17.0
tomli 2.2.1
tomlkit 0.13.3
tox 4.27.0
tox-backtick 0.6.5 <- my local copy, with changes not yet added via a PR.
tox-tags 0.2.0
tuf 6.0.0
twine 6.1.0
typing_extensions 4.14.0
typing-inspection 0.4.1
urllib3 2.2.1
virtualenv 20.31.2
wheel 0.43.0
zipp 3.23.0
Output of running tox
Output of tox -rvv
With python3.12 not found: (eg. which python3.12 -> null string ($? ==1)
$tox -rvv --override testenv.skip_missing_interpreter=True -c ~/Documents/ART-002/tox4-issue-tox.ini list
py310: 263 I find interpreter for spec PythonSpec(major=3, minor=10, free_threaded=False) [virtualenv/discovery/builtin.py:76]
py310: 264 D discover exe for PythonInfo(spec=CPython3.10.12.final.0-64, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) in /usr [virtualenv/discovery/py_info.py:451]
py310: 264 D filesystem is case-sensitive [virtualenv/info.py:27]
py310: 266 D got python info of /usr/bin/python3.10 from /home/steve/.local/share/virtualenv/py_info/2/8a94588eda9d64d9e9a351ab8144e55b1fabf5113b54e67dd26a8c27df0381b3.json [virtualenv/app_data/via_disk_folder.py:132]
py310: 266 I proposed PythonInfo(spec=CPython3.10.12.final.0-64, system=/usr/bin/python3.10, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py310: 266 D accepted PythonInfo(spec=CPython3.10.12.final.0-64, system=/usr/bin/python3.10, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:85]
py312: 306 I find interpreter for spec PythonSpec(major=3, minor=12, free_threaded=False) [virtualenv/discovery/builtin.py:76]
py312: 306 I proposed PythonInfo(spec=CPython3.10.12.final.0-64, system=/usr/bin/python3.10, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py312: 308 D discover PATH[0]=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin [virtualenv/discovery/builtin.py:152]
py312: 308 D discover PATH[1]=/opt/groovy-4.0.10/bin [virtualenv/discovery/builtin.py:152]
py312: 308 D discover PATH[2]=/usr/local/bin [virtualenv/discovery/builtin.py:152]
py312: 309 D discover PATH[3]=/usr/sbin [virtualenv/discovery/builtin.py:152]
py312: 311 D discover PATH[4]=/usr/bin [virtualenv/discovery/builtin.py:152]
py312: 315 D got python info of /usr/bin/python3 from /home/steve/.local/share/virtualenv/py_info/2/31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6.json [virtualenv/app_data/via_disk_folder.py:132]
py312: 316 I proposed PathPythonInfo(spec=CPython3.10.12.final.0-64, exe=/usr/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py312: 317 D discover PATH[5]=/sbin [virtualenv/discovery/builtin.py:152]
py312: 319 D discover PATH[6]=/bin [virtualenv/discovery/builtin.py:152]
py312: 323 D got python info of /bin/python3 from /home/steve/.local/share/virtualenv/py_info/2/916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1.json [virtualenv/app_data/via_disk_folder.py:132]
py312: 325 I proposed PathPythonInfo(spec=CPython3.10.12.final.0-64, exe=/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py312: 326 D discover PATH[7]=/usr/games [virtualenv/discovery/builtin.py:152]
py312: 326 D discover PATH[8]=/snap/bin [virtualenv/discovery/builtin.py:152]
ROOT: 326 E HandledError| replace failed in py312.set_env with RuntimeError("failed to find interpreter for Builtin discover of python_spec='py312'") [tox/run.py:23]
Running the envlist so at least 1 testenv (py310) should work, py312 be ignored:
$tox -rvv --override testenv.skip_missing_interpreter=True -c ~/Documents/ART-002/tox4-issue-tox.ini run
py310: 238 I find interpreter for spec PythonSpec(major=3, minor=10, free_threaded=False) [virtualenv/discovery/builtin.py:76]
py310: 239 D discover exe for PythonInfo(spec=CPython3.10.12.final.0-64, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) in /usr [virtualenv/discovery/py_info.py:451]
py310: 239 D filesystem is case-sensitive [virtualenv/info.py:27]
py310: 241 D got python info of /usr/bin/python3.10 from /home/steve/.local/share/virtualenv/py_info/2/8a94588eda9d64d9e9a351ab8144e55b1fabf5113b54e67dd26a8c27df0381b3.json [virtualenv/app_data/via_disk_folder.py:132]
py310: 241 I proposed PythonInfo(spec=CPython3.10.12.final.0-64, system=/usr/bin/python3.10, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py310: 241 D accepted PythonInfo(spec=CPython3.10.12.final.0-64, system=/usr/bin/python3.10, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:85]
py312: 276 I find interpreter for spec PythonSpec(major=3, minor=12, free_threaded=False) [virtualenv/discovery/builtin.py:76]
py312: 277 I proposed PythonInfo(spec=CPython3.10.12.final.0-64, system=/usr/bin/python3.10, exe=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py312: 277 D discover PATH[0]=/home/steve/PycharmProjects/tox4-test/venv-3.10/bin [virtualenv/discovery/builtin.py:152]
py312: 278 D discover PATH[1]=/opt/groovy-4.0.10/bin [virtualenv/discovery/builtin.py:152]
py312: 278 D discover PATH[2]=/usr/local/bin [virtualenv/discovery/builtin.py:152]
py312: 279 D discover PATH[3]=/usr/sbin [virtualenv/discovery/builtin.py:152]
py312: 281 D discover PATH[4]=/usr/bin [virtualenv/discovery/builtin.py:152]
py312: 287 D got python info of /usr/bin/python3 from /home/steve/.local/share/virtualenv/py_info/2/31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6.json [virtualenv/app_data/via_disk_folder.py:132]
py312: 287 I proposed PathPythonInfo(spec=CPython3.10.12.final.0-64, exe=/usr/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py312: 289 D discover PATH[5]=/sbin [virtualenv/discovery/builtin.py:152]
py312: 292 D discover PATH[6]=/bin [virtualenv/discovery/builtin.py:152]
py312: 300 D got python info of /bin/python3 from /home/steve/.local/share/virtualenv/py_info/2/916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1.json [virtualenv/app_data/via_disk_folder.py:132]
py312: 301 I proposed PathPythonInfo(spec=CPython3.10.12.final.0-64, exe=/bin/python3, platform=linux, version='3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:83]
py312: 301 D discover PATH[7]=/usr/games [virtualenv/discovery/builtin.py:152]
py312: 302 D discover PATH[8]=/snap/bin [virtualenv/discovery/builtin.py:152]
ROOT: 303 E HandledError| replace failed in py312.set_env with RuntimeError("failed to find interpreter for Builtin discover of python_spec='py312'") [tox/run.py:23]
$echo $?
254
If the substitution of {[testenv]set_env} commented out:
$tox --override testenv.skip_missing_interpreter=True -c ~/Documents/ART-002/tox4-issue-tox.ini run
py310: commands_pre[0] GitRepos/ioif/lib/ioif/client-python> .tox/py310/lib/python3.10/site-packages/run-me
py310: Exception running subprocess [Errno 2] No such file or directory: '/home/steve/Documents/ART-002/.tox/py310/lib/python3.10/site-packages/run-me'
py310: exit 2 (0.00 seconds) /home/steve/Documents/ART-002> .tox/py310/lib/python3.10/site-packages/run-me
py310: command failed but is marked ignore outcome so handling it as success
py310: commands_pre[1] GitRepos/ioif/lib/ioif/client-python> bash -c -- 'echo envbindir is /home/steve/Documents/ART-002/.tox/py310/bin'
envbindir is /home/steve/Documents/ART-002/.tox/py310/bin
py310: commands[0] GitRepos/ioif/lib/ioif/client-python> python3 -V
Python 3.10.12
py310: commands[1] GitRepos/ioif/lib/ioif/client-python> bash -c -- 'echo running out of py310 with envtmpdir == /home/steve/Documents/ART-002/.tox/py310/tmp, envsitepackagesdir == /home/steve/Documents/ART-002/.tox/py310/lib/python3.10/site-packages'
running out of py310 with envtmpdir == /home/steve/Documents/ART-002/.tox/py310/tmp, envsitepackagesdir == /home/steve/Documents/ART-002/.tox/py310/lib/python3.10/site-packages
py310: OK (0.17=setup[0.07]+cmd[0.00,0.01,0.06,0.02] seconds)
congratulations :) (0.26 seconds)
(venv-3.10) steve~/Documents/ART-002/GitRepos/ioif/lib/ioif/client-python (tox4)*
$echo $?
0
offending substitution commented out:
$tox --override testenv.skip_missing_interpreter=True -c ~/Documents/ART-002/tox4-issue-tox.ini list
default environments:
py310 -> [no description]
additional environments:
py312 -> [no description]
uncommented list:
$tox --override testenv.skip_missing_interpreter=True -c ~/Documents/ART-002/tox4-issue-tox.ini list
ROOT: HandledError| replace failed in py312.set_env with RuntimeError("failed to find interpreter for Builtin discover of python_spec='py312'")
(venv-3.10) steve~/Documents/ART-002/GitRepos/ioif/lib/ioif/client-python (tox4)*
$echo $?
254
python3.12 bin location added to PATH:
$PATH=$PATH:/opt/py312/bin tox --override testenv.skip_missing_interpreter=True -c ~/Documents/ART-002/tox4-issue-tox.ini list
default environments:
py310 -> [no description]
additional environments:
py312 -> [no description]
(venv-3.10) steve~/Documents/ART-002/GitRepos/ioif/lib/ioif/client-python (tox4)*
$echo $?
0
From my debugging session on Friday, stack frames when the replace failed exception is raised, sure looks like the nested replacement is not taking into account the skip_missing_interpreter setting. I wish I had a recommendation w/regard to a possible fix but it's early days for that, wanted to created this issue so perhaps those more familiar with the code might provided helpful feedback, ideas.
Minimal example
Here's a somewhat minimal tox.inv that will reproduce the issue: (used in the above output samples).
[tox]
envlist=py310
skip_missing_interpreters=true
[testenv]
allowlist_externals=
bash
set_env =
BASE=YES
# is is the need to replace stuff when referenced? Nope
VAR_NESTED={env:OUR_ontologies:{envdir}{/}ontologies}
# some inline JSON definition? Nope
TEST_API_KEYS=\{"ci-test": \{"uid": 1000\}\}
# what about backtick line that uses tox-backtick replacement? Nope
TWC_TIMEOUT=`+if [ "{env:DATA_SOURCE:TWC}" != "NONE" ] ; then echo {env:Job_TWC_TIMEOUT:30} ; else echo {env:Job_TWC_TIMEOUT:10} ; fi`
# any interpolation that needs virtual_env/api.py's VirtualEnv.env_site_package_dir method which returns the
# cast("Path", self.creator.purelib) <- self.creater is NOT a valid CPython object since it's not found.
DATA_DIR={envsitepackagesdir}{/}our_data{/}
TMP_DIR={envtmpdir}
commands_pre =
# apparently, only set_env replacement cause the issue.
-{envsitepackagesdir}/run-me
[testenv:{py310,py312}]
set_env =
#this next replacement usage commented, no problems.
{[testenv]set_env}
foo=yes
commands =
python3 -V
bash -c -- 'echo running out of {envname} with envtmpdir == {envtmpdir}, envsitepackagesdir == {envsitepackagesdir}'
commands_pre =
{[testenv]commands_pre}
bash -c -- 'echo envbindir is {envbindir}'