Consider the following tox.ini in an otherwise empty directory:
[tox]
envlist = py38
skipsdist = True
[base]
install_command = python -m pip install {opts} {packages}
[testenv]
install_command = {[base]install_command}
commands =
python -c 'print("Hi there ;-)")'
$ tox --version
3.21.0 imported from /tmp/venv/lib/python3.8/site-packages/tox/__init__.py
Cannot substitute install_command from the [base] section:
$ tox -rvv
using tox.ini: /tmp/test/tox.ini (pid 8575)
removing /tmp/test/.tox/log
Traceback (most recent call last):
File "/tmp/venv/bin/tox", line 8, in <module>
sys.exit(cmdline())
File "/tmp/venv/lib/python3.8/site-packages/tox/session/__init__.py", line 44, in cmdline
main(args)
File "/tmp/venv/lib/python3.8/site-packages/tox/session/__init__.py", line 65, in main
config = load_config(args)
File "/tmp/venv/lib/python3.8/site-packages/tox/session/__init__.py", line 81, in load_config
config = parseconfig(args)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 280, in parseconfig
ParseIni(config, config_file, content)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1276, in __init__
raise tox.exception.ConfigError(
tox.exception.ConfigError: ConfigError: py38 failed with ConfigError: substitution key 'opts' not found at Traceback (most recent call last):
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1252, in run
results[name] = cur_self.make_envconfig(name, section, subs, config)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1407, in make_envconfig
res = meth(env_attr.name, env_attr.default, replace=replace)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1716, in getargv_install_command
return _ArgvlistReader.getargvlist(self, s, replace=replace, name=name)[0]
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1946, in getargvlist
commands.extend(cls.getargvlist(reader, replaced, name=name))
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1948, in getargvlist
commands.append(cls.processcommand(reader, current_command, replace, name=name))
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1974, in processcommand
new_word = reader._replace(word, name=name)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1782, in _replace
replaced = Replacer(self, crossonly=crossonly).do_replace(value)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1818, in do_replace
expanded = substitute_once(value)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1816, in substitute_once
return self.RE_ITEM_REF.sub(self._replace_match, x)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1876, in _replace_match
return self._replace_substitution(sub_value)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1911, in _replace_substitution
val = self._substitute_from_other_section(sub_key)
File "/tmp/venv/lib/python3.8/site-packages/tox/config/__init__.py", line 1906, in _substitute_from_other_section
raise tox.exception.ConfigError("substitution key {!r} not found".format(key))
tox.exception.ConfigError: ConfigError: substitution key 'opts' not found
$ tox --version
3.20.1 imported from /tmp/venv/lib/python3.8/site-packages/tox/__init__.py
$ tox -r
py38 recreate: /tmp/test/.tox/py38
py38 run-test-pre: PYTHONHASHSEED='1073641419'
py38 run-test: commands[0] | python -c 'print("Hi there ;-)")'
Hi there ;-)
___________________________________________________________________________ summary ____________________________________________________________________________
py38: commands succeeded
congratulations :)
Thanks for reporting it, if you have time feel free to open a PR fixing it 馃憤
Heh, thanks for the invitation. And thanks for maintaining tox!
But I'm afraid I'm unable to spare the time right now.
I'll take a look at this, as it looks like a bug in one of my changes.
I've got a fix together - just needs a bit more polish. Will have it up today.
@gaborbernat , this should be closed now. Not sure why the commit message didnt auto-close it.
Actually it looks like a force push has deleted that commit (da140fb) on master.
Released now via https://tox.readthedocs.io/en/latest/changelog.html#v3-21-1-2021-01-13
Most helpful comment
I'll take a look at this, as it looks like a bug in one of my changes.