# Buggy code
def processcommand(cls, reader, command, replace=True):
    # Iterate through each word of the command substituting as
    # appropriate to construct the new command string. This
    # string is then broken up into exec argv components using
    # shlex.
    if replace:
        newcommand = ""
        for word in CommandParser(command).words():
            if word == "[]":
                newcommand += reader.getposargs()
                continue

            new_arg = ""
            new_word = reader._replace(word)
            new_word = reader._replace(new_word)
            new_word = Replacer._unescape(new_word)
            new_arg += new_word
            newcommand += new_arg
    else:
        newcommand = command

    # Construct shlex object that will not escape any values,
    # use all values as is in argv.
    shlexer = shlex.shlex(newcommand, posix=True)
    shlexer.whitespace_split = True
    shlexer.escape = ""
    return list(shlexer)


# 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 processcommand(cls, reader, command, replace=True, name=None):
    # Iterate through each word of the command substituting as
    # appropriate to construct the new command string. This
    # string is then broken up into exec argv components using
    # shlex.
    if replace:
        newcommand = ""
        for word in CommandParser(command).words():
            if word == "[]":
                newcommand += reader.getposargs()
                continue

            new_arg = ""
            new_word = reader._replace(word, name=name)
            new_word = reader._replace(new_word, name=name)
            new_word = Replacer._unescape(new_word)
            new_arg += new_word
            newcommand += new_arg
    else:
        newcommand = command

    # Construct shlex object that will not escape any values,
    # use all values as is in argv.
    shlexer = shlex.shlex(newcommand, posix=True)
    shlexer.whitespace_split = True
    shlexer.escape = ""
    return list(shlexer)