-
-
Notifications
You must be signed in to change notification settings - Fork 540
Open
Description
Issue
I'm trying to set some default environment variables on env_run_base
that will either pass through an existing environment variable value, or inject a default value.
This seems to always result in a CircularChainError. It only happens when the setenv
is on the env_run_base
, not when directly on the final environment. Is this a limitation of the base environment?
Environment
Provide at least:
- OS: macos Darwin Mac.mynet 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:53:27 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6041 arm64
Output of pip list
of the host Python, where tox
is installed
❯ uv pip list
Package Version
----------------- -------
cachetools 6.0.0
chardet 5.2.0
colorama 0.4.6
distlib 0.3.9
exceptiongroup 1.3.0
filelock 3.18.0
iniconfig 2.1.0
packaging 25.0
platformdirs 4.3.8
pluggy 1.6.0
pygments 2.19.1
pyproject-api 1.9.1
pytest 8.4.0
tomli 2.2.1
tox 4.26.0
typing-extensions 4.14.0
virtualenv 20.31.2
Output of running tox
Output of tox -rvv
blah on main is 📦 v0.1.0 via 🐍 v3.13.3
❯ tox
.pkg: recreate env because python changed version_info=[3, 9, 6, 'final', 0]->[3, 13, 3, 'final', 0] | executable='/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/bin/python3.9'->'/opt/homebrew/Cellar/[email protected]/3.13.3/Frameworks/Python.framework/Versions/3.13/bin/python3.13'
.pkg: remove tox env folder /Users/sam/git/blah/.tox/.pkg
.pkg: install_requires> python -I -m pip install 'setuptools>=40.8.0'
.pkg: _optional_hooks> python /opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: get_requires_for_build_sdist> python /opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: build_sdist> python /opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
py39: install_package> python -I -m pip install --force-reinstall --no-deps /Users/sam/git/blah/.tox/.tmp/package/4/blah-0.1.0.tar.gz
py39: commands[0]> pytest -vvvs
================================================================================================================================================ test session starts =================================================================================================================================================
platform darwin -- Python 3.9.6, pytest-8.4.0, pluggy-1.6.0 -- /Users/sam/git/blah/.tox/py39/bin/python
cachedir: .tox/py39/.pytest_cache
rootdir: /Users/sam/git/blah
configfile: pyproject.toml
collected 1 item
test_envecho.py::test_env None
PASSED
================================================================================================================================================= 1 passed in 0.00s ==================================================================================================================================================
py39: OK (3.39=setup[3.29]+cmd[0.10] seconds)
congratulations :) (3.43 seconds)
blah on main is 📦 v0.1.0 via 🐍 v3.13.3 took 3s
Then after setting setenv = { TESTENV = "{env:TESTENV:hello}" }
tox -rvv
py39: 84 W remove tox env folder /Users/sam/git/blah/.tox/py39 [tox/tox_env/api.py:333]
.pkg: 181 W remove tox env folder /Users/sam/git/blah/.tox/.pkg [tox/tox_env/api.py:333]
py39: 246 E internal error [tox/session/cmd/run/single.py:60]
Traceback (most recent call last):
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/session/cmd/run/single.py", line 47, in _evaluate
tox_env.setup()
~~~~~~~~~~~~~^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/api.py", line 258, in setup
self._setup_env()
~~~~~~~~~~~~~~~^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/runner.py", line 98, in _setup_env
super()._setup_env()
~~~~~~~~~~~~~~~~~~^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/api.py", line 243, in _setup_env
self.ensure_python_env()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/api.py", line 247, in ensure_python_env
conf = self.python_cache()
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/virtual_env/api.py", line 82, in python_cache
base = super().python_cache()
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/api.py", line 284, in python_cache
"version_info": list(self.base_python.version_info),
^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/api.py", line 294, in base_python
self._base_python = self._get_python(base_pythons)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/virtual_env/api.py", line 139, in _get_python
interpreter = self.creator.interpreter
^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/virtual_env/api.py", line 131, in creator
return self.session.creator
^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/virtual_env/api.py", line 111, in session
env = self.virtualenv_env_vars()
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/virtual_env/api.py", line 116, in virtualenv_env_vars
env = self.environment_variables.copy()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/python/virtual_env/api.py", line 172, in environment_variables
environment_variables = super().environment_variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/runner.py", line 193, in environment_variables
environment_variables = super().environment_variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/tox_env/api.py", line 342, in environment_variables
set_env: SetEnv = self.conf["set_env"]
~~~~~~~~~^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/sets.py", line 122, in __getitem__
return self.load(item)
~~~~~~~~~^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/sets.py", line 133, in load
return config_definition.__call__(self._conf, self.loaders, ConfigLoadArgs(chain, self.name, self.env_name)) # noqa: PLC2801
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/of_type.py", line 106, in __call__
value = loader.load(key, self.of_type, self.factory, conf, args)
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/api.py", line 148, in load
converted = self.build(key, of_type, factory, conf, raw, args)
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/toml/__init__.py", line 68, in build
exploded = Unroll(conf=conf, loader=self, args=args)(raw)
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/toml/_replace.py", line 71, in __call__
res_dict[key] = self(val, depth)
~~~~^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/toml/_replace.py", line 34, in __call__
value = replace(self.conf, reference, value, self.args)
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/replacer.py", line 70, in replace
return Replacer(conf, reference, conf_args=args, depth=depth).join(find_replace_expr(value))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/replacer.py", line 199, in join
return "".join(self(value))
~~~~^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/replacer.py", line 196, in __call__
return [self._replace_match(me) if isinstance(me, MatchExpression) else str(me) for me in value]
~~~~~~~~~~~~~~~~~~~^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/replacer.py", line 211, in _replace_match
replace_value = replace_env(self.conf, args, conf_args)
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/loader/replacer.py", line 265, in replace_env
set_env: SetEnv = env_conf.load("set_env", chain=conf_args.chain)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/sets.py", line 133, in load
return config_definition.__call__(self._conf, self.loaders, ConfigLoadArgs(chain, self.name, self.env_name)) # noqa: PLC2801
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/tox/4.26.0/libexec/lib/python3.13/site-packages/tox/config/of_type.py", line 102, in __call__
raise CircularChainError(msg)
tox.config.types.CircularChainError: circular chain detected env_run_base.setenv, env:TESTENV
py39: FAIL code 2 (0.17 seconds)
evaluation failed :( (0.19 seconds)
Minimal example
Metadata
Metadata
Assignees
Labels
No labels