# Buggy code
def _substitute_from_other_section(self, key):
    if key.startswith("[") and "]" in key:
        i = key.find("]")
        section, item = key[1:i], key[i + 1 :]
        cfg = self.reader._cfg
        if section in cfg and item in cfg[section]:
            if (section, item) in self.reader._subststack:
                raise ValueError(
                    "{} already in {}".format((section, item), self.reader._subststack),
                )
            x = str(cfg[section][item])
            return self.reader._replace(
                x,
                name=item,
                section_name=section,
                crossonly=self.crossonly,
            )

    raise tox.exception.ConfigError("substitution key {!r} not found".format(key))


# Traceback (AttributeError)
tox -vv
using tox.ini: /home/jayvdb/projects/tox/my-tox-tests/tests/tox.ini (pid 23538)
removing /home/jayvdb/projects/tox/my-tox-tests/tests/.tox/log
[wikimedia] tox-wikimedia is enabled
Traceback (most recent call last):
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/bin/tox", line 8, in <module>
sys.exit(cmdline())
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/tox/session/__init__.py", line 44, in cmdline
main(args)
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/tox/session/__init__.py", line 65, in main
config = load_config(args)
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/tox/session/__init__.py", line 81, in load_config
config = parseconfig(args)
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/tox/config/__init__.py", line 281, in parseconfig
pm.hook.tox_configure(config=config)  # post process config object
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "/home/jayvdb/.cache/tox/my-tox-tests/py38-tox3_20-other/lib/python3.8/site-packages/tox_wikimedia/__init__.py", line 93, in tox_configure
if dep in cdep.name:
AttributeError: 'str' object has no attribute 'name'

# Fixed code
def _substitute_from_other_section(self, key):
    if key.startswith("[") and "]" in key:
        i = key.find("]")
        section, item = key[1:i], key[i + 1 :]
        cfg = self.reader._cfg
        if section in cfg and item in cfg[section]:
            if (section, item) in self.reader._subststack:
                raise tox.exception.SubstitutionStackError(
                    "{} already in {}".format((section, item), self.reader._subststack),
                )
            x = str(cfg[section][item])
            return self.reader._replace(
                x,
                name=item,
                section_name=section,
                crossonly=self.crossonly,
            )

    raise tox.exception.ConfigError("substitution key {!r} not found".format(key))