diff --git a/CHANGELOG b/CHANGELOG
index 6afb70b4..3b95f4c3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,7 @@
 Not released yet
 ----------------
 
-- #p598: fix problems with implementation of #515.
+- #p599: fix problems with implementation of #515.
          Substitutions from other sections were not made anymore if they were not in `envlist`.
          Thanks to Clark Boylan (@cboylan) for helping to get this fixed (#p597).
 
diff --git a/tox/__init__.py b/tox/__init__.py
index 73d095eb..98f1246a 100644
--- a/tox/__init__.py
+++ b/tox/__init__.py
@@ -14,12 +14,18 @@ class exception:
         def __str__(self):
             return "%s: %s" % (self.__class__.__name__, self.args[0])
 
+    class MissingSubstitution(Exception):
+        FLAG = 'TOX_MISSING_SUBSTITUTION'
+        """placeholder for debugging configurations"""
+        def __init__(self, name):
+            self.name = name
+
     class ConfigError(Error):
         """ error in tox configuration. """
     class UnsupportedInterpreter(Error):
-        "signals an unsupported Interpreter"
+        """signals an unsupported Interpreter"""
     class InterpreterNotFound(Error):
-        "signals that an interpreter could not be found"
+        """signals that an interpreter could not be found"""
     class InvocationError(Error):
         """ an error while invoking a script. """
     class MissingFile(Error):
@@ -35,4 +41,5 @@ class exception:
             self.message = message
             super(exception.MinVersionError, self).__init__(message)
 
+
 from tox.session import main as cmdline  # noqa
diff --git a/tox/config.py b/tox/config.py
index 9f0024c0..d5a6baf8 100755
--- a/tox/config.py
+++ b/tox/config.py
@@ -609,6 +609,13 @@ class TestenvConfig:
         #: set of factors
         self.factors = factors
         self._reader = reader
+        self.missing_subs = []
+        """Holds substitutions that could not be resolved.
+
+        Pre 2.8.1 missing substitutions crashed with a ConfigError although this would not be a
+        problem if the env is not part of the current testrun. So we need to remember this and
+        check later when the testenv is actually run and crash only then.
+        """
 
     def get_envbindir(self):
         """ path to directory where scripts/binaries reside. """
@@ -791,9 +798,7 @@ class parseini:
             section = testenvprefix + name
             factors = set(name.split('-'))
             if section in self._cfg or factors <= known_factors:
-                config.envconfigs[name] = \
-                    self.make_envconfig(name, section, reader._subs, config,
-                                        replace=name in config.envlist)
+                config.envconfigs[name] = self.make_envconfig(name, section, reader._subs, config)
 
         all_develop = all(name in config.envconfigs
                           and config.envconfigs[name].usedevelop
@@ -813,33 +818,31 @@ class parseini:
         factors = set(name.split('-'))
         reader = SectionReader(section, self._cfg, fallbacksections=["testenv"],
                                factors=factors)
-        vc = TestenvConfig(config=config, envname=name, factors=factors, reader=reader)
-        reader.addsubstitutions(**subs)
-        reader.addsubstitutions(envname=name)
-        reader.addsubstitutions(envbindir=vc.get_envbindir,
-                                envsitepackagesdir=vc.get_envsitepackagesdir,
-                                envpython=vc.get_envpython)
-
+        tc = TestenvConfig(name, config, factors, reader)
+        reader.addsubstitutions(
+            envname=name, envbindir=tc.get_envbindir, envsitepackagesdir=tc.get_envsitepackagesdir,
+            envpython=tc.get_envpython, **subs)
         for env_attr in config._testenv_attr:
             atype = env_attr.type
-            if atype in ("bool", "path", "string", "dict", "dict_setenv", "argv", "argvlist"):
-                meth = getattr(reader, "get" + atype)
-                res = meth(env_attr.name, env_attr.default, replace=replace)
-            elif atype == "space-separated-list":
-                res = reader.getlist(env_attr.name, sep=" ")
-            elif atype == "line-list":
-                res = reader.getlist(env_attr.name, sep="\n")
-            else:
-                raise ValueError("unknown type %r" % (atype,))
-
-            if env_attr.postprocess:
-                res = env_attr.postprocess(testenv_config=vc, value=res)
-            setattr(vc, env_attr.name, res)
-
+            try:
+                if atype in ("bool", "path", "string", "dict", "dict_setenv", "argv", "argvlist"):
+                    meth = getattr(reader, "get" + atype)
+                    res = meth(env_attr.name, env_attr.default, replace=replace)
+                elif atype == "space-separated-list":
+                    res = reader.getlist(env_attr.name, sep=" ")
+                elif atype == "line-list":
+                    res = reader.getlist(env_attr.name, sep="\n")
+                else:
+                    raise ValueError("unknown type %r" % (atype,))
+                if env_attr.postprocess:
+                    res = env_attr.postprocess(testenv_config=tc, value=res)
+            except tox.exception.MissingSubstitution as e:
+                tc.missing_subs.append(e.name)
+                res = e.FLAG
+            setattr(tc, env_attr.name, res)
             if atype in ("path", "string"):
                 reader.addsubstitutions(**{env_attr.name: res})
-
-        return vc
+        return tc
 
     def _getenvdata(self, reader):
         envstr = self.config.option.env                                \
@@ -961,8 +964,7 @@ class SectionReader:
 
     def getdict_setenv(self, name, default=None, sep="\n", replace=True):
         value = self.getstring(name, None, replace=replace, crossonly=True)
-        definitions = self._getdict(value, default=default, sep=sep,
-                                    replace=replace)
+        definitions = self._getdict(value, default=default, sep=sep, replace=replace)
         self._setenv = SetenvDict(definitions, reader=self)
         return self._setenv
 
@@ -1042,9 +1044,15 @@ class SectionReader:
         section_name = section_name if section_name else self.section_name
         self._subststack.append((section_name, name))
         try:
-            return Replacer(self, crossonly=crossonly).do_replace(value)
-        finally:
+            replaced = Replacer(self, crossonly=crossonly).do_replace(value)
             assert self._subststack.pop() == (section_name, name)
+        except tox.exception.MissingSubstitution:
+            if not section_name.startswith(testenvprefix):
+                raise tox.exception.ConfigError(
+                    "substitution env:%r: unknown or recursive definition in "
+                    "section %r." % (value, section_name))
+            raise
+        return replaced
 
 
 class Replacer:
@@ -1112,20 +1120,14 @@ class Replacer:
     def _replace_env(self, match):
         envkey = match.group('substitution_value')
         if not envkey:
-            raise tox.exception.ConfigError(
-                'env: requires an environment variable name')
-
+            raise tox.exception.ConfigError('env: requires an environment variable name')
         default = match.group('default_value')
-
         envvalue = self.reader.get_environ_value(envkey)
-        if envvalue is None:
-            if default is None:
-                raise tox.exception.ConfigError(
-                    "substitution env:%r: unknown environment variable %r "
-                    " or recursive definition." %
-                    (envkey, envkey))
+        if envvalue is not None:
+            return envvalue
+        if default is not None:
             return default
-        return envvalue
+        raise tox.exception.MissingSubstitution(envkey)
 
     def _substitute_from_other_section(self, key):
         if key.startswith("[") and "]" in key:
diff --git a/tox/session.py b/tox/session.py
index 269a7705..60baaeee 100644
--- a/tox/session.py
+++ b/tox/session.py
@@ -440,6 +440,12 @@ class Session:
             path.ensure(dir=1)
 
     def setupenv(self, venv):
+        if venv.envconfig.missing_subs:
+            venv.status = (
+                "unresolvable substitution(s): %s. "
+                "Environment variables are missing or defined recursively." %
+                (','.join(["'%s'" % m for m in venv.envconfig.missing_subs])))
+            return
         if not venv.matching_platform():
             venv.status = "platform mismatch"
             return  # we simply omit non-matching platforms

2.8.0: {[testenv]setenv} substitution broken 
While installing tempest as part of devstack install, below commnd blows up with an error - 
`tox -r --notest -efull`

Error -
```
2017-09-01 18:22:20.661 | ++ lib/tempest:install_tempest:612          :   pushd /opt/stack/new/tempest
2017-09-01 18:22:20.661 | ~/tempest ~/devstack
2017-09-01 18:22:20.662 | ++ lib/tempest:install_tempest:613          :   tox -r --notest -efull
2017-09-01 18:22:21.720 | Traceback (most recent call last):
2017-09-01 18:22:21.720 |   File "/usr/local/bin/tox", line 11, in <module>
2017-09-01 18:22:21.720 |     sys.exit(cmdline())
2017-09-01 18:22:21.720 |   File "/usr/local/lib/python2.7/dist-packages/tox/session.py", line 38, in main
2017-09-01 18:22:21.720 |     config = prepare(args)
2017-09-01 18:22:21.720 |   File "/usr/local/lib/python2.7/dist-packages/tox/session.py", line 26, in prepare
2017-09-01 18:22:21.720 |     config = parseconfig(args)
2017-09-01 18:22:21.720 |   File "/usr/local/lib/python2.7/dist-packages/tox/config.py", line 242, in parseconfig
2017-09-01 18:22:21.720 |     parseini(config, inipath)
2017-09-01 18:22:21.720 |   File "/usr/local/lib/python2.7/dist-packages/tox/config.py", line 796, in __init__
2017-09-01 18:22:21.721 |     replace=name in config.envlist)
2017-09-01 18:22:21.721 |   File "/usr/local/lib/python2.7/dist-packages/tox/config.py", line 827, in make_envconfig
2017-09-01 18:22:21.721 |     res = meth(env_attr.name, env_attr.default, replace=replace)
2017-09-01 18:22:21.721 |   File "/usr/local/lib/python2.7/dist-packages/tox/config.py", line 964, in getdict_setenv
2017-09-01 18:22:21.721 |     definitions = self._getdict(value, default=default, sep=sep)
2017-09-01 18:22:21.721 |   File "/usr/local/lib/python2.7/dist-packages/tox/config.py", line 975, in _getdict
2017-09-01 18:22:21.721 |     name, rest = line.split('=', 1)
2017-09-01 18:22:21.721 | ValueError: need more than 1 value to unpack
2017-09-01 18:22:21.733 | + lib/tempest:install_tempest:1            :   exit_trap
```


Logs link - http://logs.openstack.netapp.com/ci-logs/logs/65/499765/5/upstream-check/cinder-cDOT-FCP/3566c47/logs/devstacklog.txt.gz



diff --git a/tests/test_config.py b/tests/test_config.py
index 6fa64571..2533c962 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -444,18 +444,20 @@ class TestIniParser:
         x = reader.getdict("key3", {1: 2})
         assert x == {1: 2}
 
-    def test_getstring_environment_substitution(self, monkeypatch, newconfig):
-        monkeypatch.setenv("KEY1", "hello")
-        config = newconfig("""
-            [section]
-            key1={env:KEY1}
-            key2={env:KEY2}
-        """)
-        reader = SectionReader("section", config._cfg)
-        x = reader.getstring("key1")
-        assert x == "hello"
+    def test_normal_env_sub_works(self, monkeypatch, newconfig):
+        monkeypatch.setenv("VAR", "hello")
+        config = newconfig("[section]\nkey={env:VAR}")
+        assert SectionReader("section", config._cfg).getstring("key") == "hello"
+
+    def test_missing_env_sub_raises_config_error_in_non_testenv(self, newconfig):
+        config = newconfig("[section]\nkey={env:VAR}")
         with pytest.raises(tox.exception.ConfigError):
-            reader.getstring("key2")
+            SectionReader("section", config._cfg).getstring("key")
+
+    def test_missing_env_sub_populates_missing_subs(self, newconfig):
+        config = newconfig("[testenv:foo]\ncommands={env:VAR}")
+        print(SectionReader("section", config._cfg).getstring("commands"))
+        assert config.envconfigs['foo'].missing_subs == ['VAR']
 
     def test_getstring_environment_substitution_with_default(self, monkeypatch, newconfig):
         monkeypatch.setenv("KEY1", "hello")
diff --git a/tests/test_z_cmdline.py b/tests/test_z_cmdline.py
index 49e7641f..97e0712b 100644
--- a/tests/test_z_cmdline.py
+++ b/tests/test_z_cmdline.py
@@ -871,3 +871,10 @@ def test_envtmpdir(initproj, cmd):
 
     result = cmd.run("tox")
     assert not result.ret
+
+
+def test_missing_env_fails(initproj, cmd):
+    initproj("foo", filedefs={'tox.ini': "[testenv:foo]\ncommands={env:VAR}"})
+    result = cmd.run("tox")
+    assert result.ret == 1
+    result.stdout.fnmatch_lines(["*foo: unresolvable substitution(s): 'VAR'*"])

pip install -e .[dev]
parse_log_pytest
pytest
pytest pytest-timeout
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
certifi==2021.5.30
distlib==0.3.9
filelock==3.4.1
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
platformdirs==2.4.0
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pytest==6.2.4
pytest-timeout==2.1.0
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
-e git+https://github.com/tox-dev/tox.git@aee874c0b48698bb8d4e2afba18713a8aeb32011#egg=tox
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
virtualenv==20.17.1
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: tox
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - distlib==0.3.9
      - filelock==3.4.1
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - platformdirs==2.4.0
      - pytest-timeout==2.1.0
      - virtualenv==20.17.1
prefix: /opt/conda/envs/tox

tests/test_config.py::TestIniParserAgainstCommandsKey::test_regression_issue595 tests/test_config.py::TestIniParser::test_missing_env_sub_populates_missing_subs tests/test_z_cmdline.py::test_missing_env_fails
test_hello.py::test_fail tests/test_config.py::TestVenvConfig::test_force_dep_with_url tests/test_config.py::TestIniParser::test_getbool tests/test_z_cmdline.py::test_report_protocol tests/test_z_cmdline.py::test__resolve_pkg
tests/test_config.py::TestVenvConfig::test_config_parsing_minimal tests/test_config.py::TestVenvConfig::test_config_parsing_multienv tests/test_config.py::TestVenvConfig::test_envdir_set_manually tests/test_config.py::TestVenvConfig::test_envdir_set_manually_with_substitutions tests/test_config.py::TestVenvConfig::test_force_dep_version tests/test_config.py::TestVenvConfig::test_is_same_dep tests/test_config.py::TestConfigPlatform::test_config_parse_platform tests/test_config.py::TestConfigPlatform::test_config_parse_platform_rex tests/test_config.py::TestConfigPlatform::test_config_parse_platform_with_factors[win] tests/test_config.py::TestConfigPlatform::test_config_parse_platform_with_factors[lin] tests/test_config.py::TestConfigPackage::test_defaults tests/test_config.py::TestConfigPackage::test_defaults_distshare tests/test_config.py::TestConfigPackage::test_defaults_changed_dir tests/test_config.py::TestConfigPackage::test_project_paths tests/test_config.py::TestParseconfig::test_search_parents tests/test_config.py::TestParseconfig::test_explicit_config_path tests/test_config.py::test_get_homedir tests/test_config.py::TestGetcontextname::test_blank tests/test_config.py::TestGetcontextname::test_jenkins tests/test_config.py::TestGetcontextname::test_hudson_legacy tests/test_config.py::TestIniParserAgainstCommandsKey::test_command_substitution_from_other_section tests/test_config.py::TestIniParserAgainstCommandsKey::test_command_substitution_from_other_section_multiline tests/test_config.py::TestIniParserAgainstCommandsKey::test_command_substitution_from_other_section_posargs tests/test_config.py::TestIniParserAgainstCommandsKey::test_command_section_and_posargs_substitution tests/test_config.py::TestIniParserAgainstCommandsKey::test_command_env_substitution tests/test_config.py::TestIniParserAgainstCommandsKey::test_command_env_substitution_global tests/test_config.py::TestIniParser::test_getstring_single tests/test_config.py::TestIniParser::test_missing_substitution tests/test_config.py::TestIniParser::test_getstring_fallback_sections tests/test_config.py::TestIniParser::test_getstring_substitution tests/test_config.py::TestIniParser::test_getlist tests/test_config.py::TestIniParser::test_getdict tests/test_config.py::TestIniParser::test_normal_env_sub_works tests/test_config.py::TestIniParser::test_missing_env_sub_raises_config_error_in_non_testenv tests/test_config.py::TestIniParser::test_getstring_environment_substitution_with_default tests/test_config.py::TestIniParser::test_value_matches_section_substituion tests/test_config.py::TestIniParser::test_value_doesn_match_section_substitution tests/test_config.py::TestIniParser::test_getstring_other_section_substitution tests/test_config.py::TestIniParser::test_argvlist tests/test_config.py::TestIniParser::test_argvlist_windows_escaping tests/test_config.py::TestIniParser::test_argvlist_multiline tests/test_config.py::TestIniParser::test_argvlist_quoting_in_command tests/test_config.py::TestIniParser::test_argvlist_comment_after_command tests/test_config.py::TestIniParser::test_argvlist_command_contains_hash tests/test_config.py::TestIniParser::test_argvlist_positional_substitution tests/test_config.py::TestIniParser::test_argvlist_quoted_posargs tests/test_config.py::TestIniParser::test_argvlist_posargs_with_quotes tests/test_config.py::TestIniParser::test_positional_arguments_are_only_replaced_when_standing_alone tests/test_config.py::TestIniParser::test_posargs_are_added_escaped_issue310 tests/test_config.py::TestIniParser::test_substitution_with_multiple_words tests/test_config.py::TestIniParser::test_getargv tests/test_config.py::TestIniParser::test_getpath tests/test_config.py::TestIniParserPrefix::test_basic_section_access tests/test_config.py::TestIniParserPrefix::test_fallback_sections tests/test_config.py::TestIniParserPrefix::test_value_matches_prefixed_section_substituion tests/test_config.py::TestIniParserPrefix::test_value_doesn_match_prefixed_section_substitution tests/test_config.py::TestIniParserPrefix::test_other_section_substitution tests/test_config.py::TestConfigTestEnv::test_commentchars_issue33 tests/test_config.py::TestConfigTestEnv::test_defaults tests/test_config.py::TestConfigTestEnv::test_sitepackages_switch tests/test_config.py::TestConfigTestEnv::test_installpkg_tops_develop tests/test_config.py::TestConfigTestEnv::test_specific_command_overrides tests/test_config.py::TestConfigTestEnv::test_whitelist_externals tests/test_config.py::TestConfigTestEnv::test_changedir tests/test_config.py::TestConfigTestEnv::test_ignore_errors tests/test_config.py::TestConfigTestEnv::test_envbindir tests/test_config.py::TestConfigTestEnv::test_envbindir_jython[jython] tests/test_config.py::TestConfigTestEnv::test_envbindir_jython[pypy] tests/test_config.py::TestConfigTestEnv::test_envbindir_jython[pypy3] tests/test_config.py::TestConfigTestEnv::test_passenv_as_multiline_list[win32] tests/test_config.py::TestConfigTestEnv::test_passenv_as_multiline_list[linux2] tests/test_config.py::TestConfigTestEnv::test_passenv_as_space_separated_list[win32] tests/test_config.py::TestConfigTestEnv::test_passenv_as_space_separated_list[linux2] tests/test_config.py::TestConfigTestEnv::test_passenv_with_factor tests/test_config.py::TestConfigTestEnv::test_passenv_from_global_env tests/test_config.py::TestConfigTestEnv::test_passenv_glob_from_global_env tests/test_config.py::TestConfigTestEnv::test_changedir_override tests/test_config.py::TestConfigTestEnv::test_install_command_setting tests/test_config.py::TestConfigTestEnv::test_install_command_must_contain_packages tests/test_config.py::TestConfigTestEnv::test_install_command_substitutions tests/test_config.py::TestConfigTestEnv::test_pip_pre tests/test_config.py::TestConfigTestEnv::test_pip_pre_cmdline_override tests/test_config.py::TestConfigTestEnv::test_simple tests/test_config.py::TestConfigTestEnv::test_substitution_error tests/test_config.py::TestConfigTestEnv::test_substitution_defaults tests/test_config.py::TestConfigTestEnv::test_substitution_notfound_issue246 tests/test_config.py::TestConfigTestEnv::test_substitution_notfound_issue515 tests/test_config.py::TestConfigTestEnv::test_substitution_nested_env_defaults tests/test_config.py::TestConfigTestEnv::test_substitution_positional tests/test_config.py::TestConfigTestEnv::test_substitution_noargs_issue240 tests/test_config.py::TestConfigTestEnv::test_substitution_double tests/test_config.py::TestConfigTestEnv::test_posargs_backslashed_or_quoted tests/test_config.py::TestConfigTestEnv::test_rewrite_posargs tests/test_config.py::TestConfigTestEnv::test_rewrite_simple_posargs tests/test_config.py::TestConfigTestEnv::test_take_dependencies_from_other_testenv[envlist0-deps0] tests/test_config.py::TestConfigTestEnv::test_take_dependencies_from_other_testenv[envlist1-deps1] tests/test_config.py::TestConfigTestEnv::test_take_dependencies_from_other_section tests/test_config.py::TestConfigTestEnv::test_multilevel_substitution tests/test_config.py::TestConfigTestEnv::test_recursive_substitution_cycle_fails tests/test_config.py::TestConfigTestEnv::test_single_value_from_other_secton tests/test_config.py::TestConfigTestEnv::test_factors tests/test_config.py::TestConfigTestEnv::test_factor_ops tests/test_config.py::TestConfigTestEnv::test_default_factors tests/test_config.py::TestConfigTestEnv::test_factors_in_boolean tests/test_config.py::TestConfigTestEnv::test_factors_in_setenv tests/test_config.py::TestConfigTestEnv::test_factor_use_not_checked tests/test_config.py::TestConfigTestEnv::test_factors_groups_touch tests/test_config.py::TestConfigTestEnv::test_period_in_factor tests/test_config.py::TestConfigTestEnv::test_ignore_outcome tests/test_config.py::TestGlobalOptions::test_notest tests/test_config.py::TestGlobalOptions::test_verbosity tests/test_config.py::TestGlobalOptions::test_substitution_jenkins_default tests/test_config.py::TestGlobalOptions::test_substitution_jenkins_context tests/test_config.py::TestGlobalOptions::test_sdist_specification tests/test_config.py::TestGlobalOptions::test_env_selection tests/test_config.py::TestGlobalOptions::test_py_venv tests/test_config.py::TestGlobalOptions::test_default_environments tests/test_config.py::TestGlobalOptions::test_envlist_expansion tests/test_config.py::TestGlobalOptions::test_envlist_cross_product tests/test_config.py::TestGlobalOptions::test_envlist_multiline tests/test_config.py::TestGlobalOptions::test_minversion tests/test_config.py::TestGlobalOptions::test_skip_missing_interpreters_true tests/test_config.py::TestGlobalOptions::test_skip_missing_interpreters_false tests/test_config.py::TestGlobalOptions::test_defaultenv_commandline tests/test_config.py::TestGlobalOptions::test_defaultenv_partial_override tests/test_config.py::TestHashseedOption::test_default tests/test_config.py::TestHashseedOption::test_passing_integer tests/test_config.py::TestHashseedOption::test_passing_string tests/test_config.py::TestHashseedOption::test_passing_empty_string tests/test_config.py::TestHashseedOption::test_passing_no_argument tests/test_config.py::TestHashseedOption::test_setenv tests/test_config.py::TestHashseedOption::test_noset tests/test_config.py::TestHashseedOption::test_noset_with_setenv tests/test_config.py::TestHashseedOption::test_one_random_hashseed tests/test_config.py::TestHashseedOption::test_setenv_in_one_testenv tests/test_config.py::TestSetenv::test_getdict_lazy tests/test_config.py::TestSetenv::test_getdict_lazy_update tests/test_config.py::TestSetenv::test_setenv_uses_os_environ tests/test_config.py::TestSetenv::test_setenv_default_os_environ tests/test_config.py::TestSetenv::test_setenv_uses_other_setenv tests/test_config.py::TestSetenv::test_setenv_recursive_direct tests/test_config.py::TestSetenv::test_setenv_overrides tests/test_config.py::TestSetenv::test_setenv_with_envdir_and_basepython tests/test_config.py::TestSetenv::test_setenv_ordering_1 tests/test_config.py::TestSetenv::test_setenv_cross_section_subst_issue294 tests/test_config.py::TestSetenv::test_setenv_cross_section_subst_twice tests/test_config.py::TestSetenv::test_setenv_cross_section_mixed tests/test_config.py::TestIndexServer::test_indexserver tests/test_config.py::TestIndexServer::test_parse_indexserver tests/test_config.py::TestIndexServer::test_multiple_homedir_relative_local_indexservers tests/test_config.py::TestConfigConstSubstitutions::test_replace_pathsep_unix[:] tests/test_config.py::TestConfigConstSubstitutions::test_replace_pathsep_unix[;] tests/test_config.py::TestConfigConstSubstitutions::test_pathsep_regex tests/test_config.py::TestParseEnv::test_parse_recreate tests/test_config.py::TestCmdInvocation::test_help tests/test_config.py::TestCmdInvocation::test_version tests/test_config.py::TestCmdInvocation::test_listenvs tests/test_config.py::TestCmdInvocation::test_listenvs_verbose_description tests/test_config.py::TestCmdInvocation::test_listenvs_all tests/test_config.py::TestCmdInvocation::test_listenvs_all_verbose_description tests/test_config.py::TestCmdInvocation::test_listenvs_all_verbose_description_no_additional_environments tests/test_config.py::TestCmdInvocation::test_config_specific_ini tests/test_config.py::TestCmdInvocation::test_no_tox_ini tests/test_config.py::TestCmdInvocation::test_override_workdir tests/test_config.py::TestCmdInvocation::test_showconfig_with_force_dep_version tests/test_config.py::test_env_spec[-e tests/test_config.py::TestCommandParser::test_command_parser_for_word tests/test_config.py::TestCommandParser::test_command_parser_for_posargs tests/test_config.py::TestCommandParser::test_command_parser_for_multiple_words tests/test_config.py::TestCommandParser::test_command_parser_for_substitution_with_spaces tests/test_config.py::TestCommandParser::test_command_parser_with_complex_word_set tests/test_config.py::TestCommandParser::test_command_with_runs_of_whitespace tests/test_config.py::TestCommandParser::test_command_with_split_line_in_subst_arguments tests/test_config.py::TestCommandParser::test_command_parsing_for_issue_10 tests/test_z_cmdline.py::test__resolve_pkg_doubledash tests/test_z_cmdline.py::TestSession::test_make_sdist tests/test_z_cmdline.py::TestSession::test_make_sdist_distshare tests/test_z_cmdline.py::TestSession::test_log_pcall tests/test_z_cmdline.py::TestSession::test_summary_status tests/test_z_cmdline.py::TestSession::test_getvenv tests/test_z_cmdline.py::test_minversion tests/test_z_cmdline.py::test_notoxini_help_still_works tests/test_z_cmdline.py::test_notoxini_help_ini_still_works tests/test_z_cmdline.py::test_envdir_equals_toxini_errors_out tests/test_z_cmdline.py::test_run_custom_install_command_error tests/test_z_cmdline.py::test_unknown_interpreter_and_env tests/test_z_cmdline.py::test_unknown_interpreter tests/test_z_cmdline.py::test_skip_platform_mismatch tests/test_z_cmdline.py::test_skip_unknown_interpreter tests/test_z_cmdline.py::test_unknown_dep tests/test_z_cmdline.py::test_venv_special_chars_issue252 tests/test_z_cmdline.py::test_unknown_environment tests/test_z_cmdline.py::test_skip_sdist tests/test_z_cmdline.py::test_minimal_setup_py_empty tests/test_z_cmdline.py::test_minimal_setup_py_comment_only tests/test_z_cmdline.py::test_minimal_setup_py_non_functional tests/test_z_cmdline.py::test_sdist_fails tests/test_z_cmdline.py::test_package_install_fails tests/test_z_cmdline.py::TestToxRun::test_toxuone_env tests/test_z_cmdline.py::TestToxRun::test_different_config_cwd tests/test_z_cmdline.py::TestToxRun::test_json tests/test_z_cmdline.py::test_develop tests/test_z_cmdline.py::test_usedevelop tests/test_z_cmdline.py::test_usedevelop_mixed tests/test_z_cmdline.py::test_test_usedevelop[.] tests/test_z_cmdline.py::test_test_usedevelop[src] tests/test_z_cmdline.py::test_alwayscopy tests/test_z_cmdline.py::test_alwayscopy_default tests/test_z_cmdline.py::test_test_piphelp tests/test_z_cmdline.py::test_notest tests/test_z_cmdline.py::test_PYC tests/test_z_cmdline.py::test_env_VIRTUALENV_PYTHON tests/test_z_cmdline.py::test_sdistonly tests/test_z_cmdline.py::test_separate_sdist_no_sdistfile tests/test_z_cmdline.py::test_separate_sdist tests/test_z_cmdline.py::test_sdist_latest tests/test_z_cmdline.py::test_installpkg tests/test_z_cmdline.py::test_envsitepackagesdir tests/test_z_cmdline.py::test_envsitepackagesdir_skip_missing_issue280 tests/test_z_cmdline.py::test_verbosity[] tests/test_z_cmdline.py::test_verbosity[-v] tests/test_z_cmdline.py::test_verbosity[-vv] tests/test_z_cmdline.py::test_envtmpdir
tox/__init__.py tox/config.py tox/session.py CHANGELOG
tox/__init__.py tox/config.py tox/session.py CHANGELOG