Repository: tox-dev/tox

Issue:
[BUG] tox congratulates me even if I ^C it
Fortunately it exits nonzero so this is more of a cosmetic issue than anything else:

```console
$ tox -e py37
GLOB sdist-make: /home/asottile/workspace/pluggy/setup.py
py37 create: /home/asottile/workspace/pluggy/.tox/py37
^CERROR: got KeyboardInterrupt signal
___________________________________ summary ____________________________________
  py37: commands succeeded
  congratulations :)
$ echo $?
2
$ tox --version
3.8.6 imported from /home/asottile/opt/venv/lib/python3.6/site-packages/tox/__init__.py
registered plugins:
    tox-virtualenv-no-download-1.1.0 at /home/asottile/opt/venv/lib/python3.6/site-packages/tox_virtualenv_no_download.py
    tox-pip-extensions-1.6.0 at /home/asottile/opt/venv/lib/python3.6/site-packages/tox_pip_extensions.py
```

Discussion:
asottile: It passed before, I think this is a flake / issue with pytest-xdist / pytest -- can you rerun it?
gaborbernat: Triggered a rerun 👍 
gaborbernat: What's the flake issue with pytest-xdist?
asottile: > What's the flake issue with pytest-xdist?

It has to do with printing non-ascii characters in error messages during pytest failures and multiprocessing in python2.x specifically on windows -- I've had a rough time trying to reproduce it myself but here's the stacktrace (I've seen this before):

```
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\main.py", line 209, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\main.py", line 249, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "<remote exec>", line 67, in pytest_runtestloop
INTERNALERROR>   File "<remote exec>", line 84, in run_one_test
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 78, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 93, in runtestprotocol
INTERNALERROR>     reports.append(call_and_report(item, "call", log))
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 175, in call_and_report
INTERNALERROR>     report = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 203, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\skipping.py", line 127, in pytest_runtest_makereport
INTERNALERROR>     rep = outcome.get_result()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 249, in pytest_runtest_makereport
INTERNALERROR>     return TestReport.from_item_and_call(item, call)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\reports.py", line 361, in from_item_and_call
INTERNALERROR>     longrepr = item.repr_failure(excinfo)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\python.py", line 848, in repr_failure
INTERNALERROR>     return self._repr_failure_py(excinfo, style=style)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\nodes.py", line 285, in _repr_failure_py
INTERNALERROR>     truncate_locals=truncate_locals,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 552, in getrepr
INTERNALERROR>     return fmt.repr_excinfo(self)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 790, in repr_excinfo
INTERNALERROR>     reprtraceback = self.repr_traceback(excinfo)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 747, in repr_traceback
INTERNALERROR>     reprentry = self.repr_traceback_entry(entry, einfo)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 717, in repr_traceback_entry
INTERNALERROR>     localsrepr = self.repr_locals(entry.locals)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 679, in repr_locals
INTERNALERROR>     str_repr = pprint.pformat(value)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 63, in pformat
INTERNALERROR>     return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 122, in pformat
INTERNALERROR>     self._format(object, sio, 0, 0, {}, 0)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 140, in _format
INTERNALERROR>     rep = self._repr(object, context, level - 1)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 226, in _repr
INTERNALERROR>     self._depth, level)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 238, in format
INTERNALERROR>     return _safe_repr(object, context, maxlevels, level)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 323, in _safe_repr
INTERNALERROR>     rep = repr(object)
INTERNALERROR> UnicodeEncodeError: 'ascii' codec can't encode character u'\u280b' in position 40: ordinal not in range(128)

INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\main.py", line 209, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\main.py", line 249, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 203, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\xdist\dsession.py", line 115, in pytest_runtestloop
INTERNALERROR>     self.loop_once()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\xdist\dsession.py", line 138, in loop_once
INTERNALERROR>     call(**kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\xdist\dsession.py", line 180, in worker_workerfinished
INTERNALERROR>     assert not crashitem, (crashitem, node)
INTERNALERROR> AssertionError: ('tests/unit/session/test_parallel.py::test_parallel_show_output', <WorkerController gw1>)
INTERNALERROR> assert not 'tests/unit/session/test_parallel.py::test_parallel_show_output'
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\main.py", line 209, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\main.py", line 249, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "<remote exec>", line 67, in pytest_runtestloop
INTERNALERROR>   File "<remote exec>", line 84, in run_one_test
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 78, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 93, in runtestprotocol
INTERNALERROR>     reports.append(call_and_report(item, "call", log))
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 175, in call_and_report
INTERNALERROR>     report = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 68, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\manager.py", line 62, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 203, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\skipping.py", line 127, in pytest_runtest_makereport
INTERNALERROR>     rep = outcome.get_result()
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 81, in get_result
INTERNALERROR>     _reraise(*ex)  # noqa
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\runner.py", line 249, in pytest_runtest_makereport
INTERNALERROR>     return TestReport.from_item_and_call(item, call)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\reports.py", line 361, in from_item_and_call
INTERNALERROR>     longrepr = item.repr_failure(excinfo)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\python.py", line 848, in repr_failure
INTERNALERROR>     return self._repr_failure_py(excinfo, style=style)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\nodes.py", line 285, in _repr_failure_py
INTERNALERROR>     truncate_locals=truncate_locals,
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 552, in getrepr
INTERNALERROR>     return fmt.repr_excinfo(self)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 790, in repr_excinfo
INTERNALERROR>     reprtraceback = self.repr_traceback(excinfo)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 747, in repr_traceback
INTERNALERROR>     reprentry = self.repr_traceback_entry(entry, einfo)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 717, in repr_traceback_entry
INTERNALERROR>     localsrepr = self.repr_locals(entry.locals)
INTERNALERROR>   File "d:\a\1\s\.tox\py27\lib\site-packages\_pytest\_code\code.py", line 679, in repr_locals
INTERNALERROR>     str_repr = pprint.pformat(value)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 63, in pformat
INTERNALERROR>     return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 122, in pformat
INTERNALERROR>     self._format(object, sio, 0, 0, {}, 0)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 140, in _format
INTERNALERROR>     rep = self._repr(object, context, level - 1)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 226, in _repr
INTERNALERROR>     self._depth, level)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 238, in format
INTERNALERROR>     return _safe_repr(object, context, maxlevels, level)
INTERNALERROR>   File "C:\hostedtoolcache\windows\Python\2.7.14\x64\Lib\pprint.py", line 323, in _safe_repr
INTERNALERROR>     rep = repr(object)
INTERNALERROR> UnicodeEncodeError: 'ascii' codec can't encode character u'\u280b' in position 218: ordinal not in range(128)
```
asottile: looks like it didn't trigger, I'll just trivial-amend

Patch:
diff --git a/docs/changelog/1257.bugfix.rst b/docs/changelog/1257.bugfix.rst
new file mode 100644
index 00000000..f18ff223
--- /dev/null
+++ b/docs/changelog/1257.bugfix.rst
@@ -0,0 +1,1 @@
+Fix ``congratulations`` when using ``^C`` during virtualenv creation - by :user:`asottile`
diff --git a/src/tox/venv.py b/src/tox/venv.py
index fd7344ea..22e7e7ae 100644
--- a/src/tox/venv.py
+++ b/src/tox/venv.py
@@ -669,13 +669,17 @@ def tox_testenv_create(venv, action):
     base_path.ensure(dir=1)
     args.append(venv.path.basename)
     if not _SKIP_VENV_CREATION:
-        venv._pcall(
-            args,
-            venv=False,
-            action=action,
-            cwd=base_path,
-            redirect=reporter.verbosity() < reporter.Verbosity.DEBUG,
-        )
+        try:
+            venv._pcall(
+                args,
+                venv=False,
+                action=action,
+                cwd=base_path,
+                redirect=reporter.verbosity() < reporter.Verbosity.DEBUG,
+            )
+        except KeyboardInterrupt:
+            venv.status = "keyboardinterrupt"
+            raise
     return True  # Return non-None to indicate plugin has completed
 
 


Test patch:
diff --git a/tests/unit/test_venv.py b/tests/unit/test_venv.py
index 0558a2e5..da6298e4 100644
--- a/tests/unit/test_venv.py
+++ b/tests/unit/test_venv.py
@@ -24,10 +24,10 @@ def test_getdigest(tmpdir):
 def test_getsupportedinterpreter(monkeypatch, newconfig, mocksession):
     config = newconfig(
         [],
-        """
+        """\
         [testenv:python]
         basepython={}
-    """.format(
+        """.format(
             sys.executable
         ),
     )
@@ -57,9 +57,9 @@ def test_getsupportedinterpreter(monkeypatch, newconfig, mocksession):
 def test_create(mocksession, newconfig):
     config = newconfig(
         [],
-        """
+        """\
         [testenv:py123]
-    """,
+        """,
     )
     envconfig = config.envconfigs["py123"]
     mocksession.new_config(config)
@@ -83,12 +83,28 @@ def test_create(mocksession, newconfig):
     assert venv.path_config.check(exists=False)
 
 
+def test_create_KeyboardInterrupt(mocksession, newconfig, mocker):
+    config = newconfig(
+        [],
+        """\
+        [testenv:py123]
+        """,
+    )
+    mocksession.new_config(config)
+    venv = mocksession.getvenv("py123")
+    with mocker.patch.object(venv, "_pcall", side_effect=KeyboardInterrupt):
+        with pytest.raises(KeyboardInterrupt):
+            venv.setupenv()
+
+    assert venv.status == "keyboardinterrupt"
+
+
 def test_commandpath_venv_precedence(tmpdir, monkeypatch, mocksession, newconfig):
     config = newconfig(
         [],
-        """
+        """\
         [testenv:py123]
-    """,
+        """,
     )
     mocksession.new_config(config)
     venv = mocksession.getvenv("py123")
@@ -103,13 +119,13 @@ def test_commandpath_venv_precedence(tmpdir, monkeypatch, mocksession, newconfig
 def test_create_sitepackages(mocksession, newconfig):
     config = newconfig(
         [],
-        """
+        """\
         [testenv:site]
         sitepackages=True
 
         [testenv:nosite]
         sitepackages=False
-    """,
+        """,
     )
     mocksession.new_config(config)
     venv = mocksession.getvenv("site")
@@ -134,13 +150,13 @@ def test_create_sitepackages(mocksession, newconfig):
 def test_install_deps_wildcard(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [tox]
         distshare = {toxworkdir}/distshare
         [testenv:py123]
         deps=
             {distshare}/dep1-*
-    """,
+        """,
     )
     venv = mocksession.getvenv("py123")
     with mocksession.newaction(venv.name, "getenv") as action:
@@ -166,7 +182,7 @@ def test_install_deps_wildcard(newmocksession):
 def test_install_deps_indexserver(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [tox]
         indexserver =
             abc = ABC
@@ -176,7 +192,7 @@ def test_install_deps_indexserver(newmocksession):
             dep1
             :abc:dep2
             :abc2:dep3
-    """,
+        """,
     )
     venv = mocksession.getvenv("py123")
     with mocksession.newaction(venv.name, "getenv") as action:
@@ -203,12 +219,12 @@ def test_install_deps_indexserver(newmocksession):
 def test_install_deps_pre(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         pip_pre=true
         deps=
             dep1
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     with mocksession.newaction(venv.name, "getenv") as action:
@@ -227,11 +243,11 @@ def test_install_deps_pre(newmocksession):
 def test_installpkg_indexserver(newmocksession, tmpdir):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [tox]
         indexserver =
             default = ABC
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     pcalls = mocksession._pcalls
@@ -247,10 +263,10 @@ def test_install_recreate(newmocksession, tmpdir):
     pkg = tmpdir.ensure("package.tar.gz")
     mocksession = newmocksession(
         ["--recreate"],
-        """
+        """\
         [testenv]
         deps=xyz
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
 
@@ -265,11 +281,11 @@ def test_install_recreate(newmocksession, tmpdir):
 def test_install_sdist_extras(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         extras = testing
             development
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     with mocksession.newaction(venv.name, "getenv") as action:
@@ -285,11 +301,11 @@ def test_install_sdist_extras(newmocksession):
 def test_develop_extras(newmocksession, tmpdir):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         extras = testing
             development
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     with mocksession.newaction(venv.name, "getenv") as action:
@@ -309,12 +325,12 @@ def test_env_variables_added_to_needs_reinstall(tmpdir, mocksession, newconfig,
     monkeypatch.setenv("TEMP_NOPASS_VAR", "456")
     config = newconfig(
         [],
-        """
+        """\
         [testenv:python]
         passenv = temp_pass_var
         setenv =
             CUSTOM_VAR = 789
-    """,
+        """,
     )
     mocksession.new_config(config)
     venv = mocksession.getvenv("python")
@@ -353,10 +369,10 @@ def test_test_hashseed_is_in_output(newmocksession, monkeypatch):
 def test_test_runtests_action_command_is_in_output(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         commands = echo foo bar
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     with mocksession.newaction(venv.name, "update") as action:
@@ -368,12 +384,12 @@ def test_test_runtests_action_command_is_in_output(newmocksession):
 def test_install_error(newmocksession):
     mocksession = newmocksession(
         ["--recreate"],
-        """
+        """\
         [testenv]
         deps=xyz
         commands=
             qwelkqw
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     venv.test()
@@ -384,11 +400,11 @@ def test_install_error(newmocksession):
 def test_install_command_not_installed(newmocksession):
     mocksession = newmocksession(
         ["--recreate"],
-        """
+        """\
         [testenv]
         commands=
             pytest
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     venv.status = 0
@@ -400,14 +416,14 @@ def test_install_command_not_installed(newmocksession):
 def test_install_command_whitelisted(newmocksession):
     mocksession = newmocksession(
         ["--recreate"],
-        """
+        """\
         [testenv]
         whitelist_externals = pytest
                               xy*
         commands=
             pytest
             xyz
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     venv.test()
@@ -418,11 +434,11 @@ def test_install_command_whitelisted(newmocksession):
 def test_install_command_not_installed_bash(newmocksession):
     mocksession = newmocksession(
         ["--recreate"],
-        """
+        """\
         [testenv]
         commands=
             bash
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     venv.test()
@@ -434,13 +450,13 @@ def test_install_python3(newmocksession):
         pytest.skip("needs python3")
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv:py123]
         basepython=python3
         deps=
             dep1
             dep2
-    """,
+        """,
     )
     venv = mocksession.getvenv("py123")
     with mocksession.newaction(venv.name, "getenv") as action:
@@ -476,20 +492,20 @@ class TestCreationConfig:
     def test_matchingdependencies(self, newconfig, mocksession):
         config = newconfig(
             [],
-            """
+            """\
             [testenv]
             deps=abc
-        """,
+            """,
         )
         mocksession.new_config(config)
         venv = mocksession.getvenv("python")
         cconfig = venv._getliveconfig()
         config = newconfig(
             [],
-            """
+            """\
             [testenv]
             deps=xyz
-        """,
+            """,
         )
         mocksession.new_config(config)
         venv = mocksession.getvenv("python")
@@ -499,13 +515,13 @@ class TestCreationConfig:
     def test_matchingdependencies_file(self, newconfig, mocksession):
         config = newconfig(
             [],
-            """
+            """\
             [tox]
             distshare={toxworkdir}/distshare
             [testenv]
             deps=abc
                  {distshare}/xyz.zip
-        """,
+            """,
         )
         xyz = config.distshare.join("xyz.zip")
         xyz.ensure()
@@ -520,12 +536,12 @@ class TestCreationConfig:
     def test_matchingdependencies_latest(self, newconfig, mocksession):
         config = newconfig(
             [],
-            """
+            """\
             [tox]
             distshare={toxworkdir}/distshare
             [testenv]
             deps={distshare}/xyz-*
-        """,
+            """,
         )
         config.distshare.ensure("xyz-1.2.0.zip")
         xyz2 = config.distshare.ensure("xyz-1.2.1.zip")
@@ -597,10 +613,10 @@ class TestVenvTest:
         monkeypatch.setenv("PIP_RESPECT_VIRTUALENV", "1")
         mocksession = newmocksession(
             [],
-            """
+            """\
             [testenv:python]
             commands=abc
-        """,
+            """,
         )
         venv = mocksession.getvenv("python")
         with mocksession.newaction(venv.name, "getenv") as action:
@@ -643,10 +659,10 @@ class TestVenvTest:
         monkeypatch.setenv("PYTHONPATH", "/my/awesome/library")
         mocksession = newmocksession(
             [],
-            """
+            """\
             [testenv:python]
             commands=abc
-        """,
+            """,
         )
         venv = mocksession.getvenv("python")
         with mocksession.newaction(venv.name, "getenv") as action:
@@ -662,11 +678,11 @@ class TestVenvTest:
         monkeypatch.setenv("PYTHONPATH", "/my/awesome/library")
         mocksession = newmocksession(
             [],
-            """
+            """\
             [testenv:python]
             commands=abc
             passenv = PYTHONPATH
-        """,
+            """,
         )
         venv = mocksession.getvenv("python")
         with mocksession.newaction(venv.name, "getenv") as action:
@@ -682,10 +698,10 @@ class TestVenvTest:
         monkeypatch.setenv("PYTHONPATH", "")
         mocksession = newmocksession(
             [],
-            """
+            """\
             [testenv:python]
             commands=abc
-        """,
+            """,
         )
         venv = mocksession.getvenv("python")
         with mocksession.newaction(venv.name, "getenv") as action:
@@ -707,14 +723,14 @@ def test_env_variables_added_to_pcall(tmpdir, mocksession, newconfig, monkeypatc
     monkeypatch.setenv("YY", "456")
     config = newconfig(
         [],
-        """
+        """\
         [testenv:python]
         commands=python -V
         passenv = x123
         setenv =
             ENV_VAR = value
             PYTHONPATH = value
-    """,
+        """,
     )
     mocksession._clearmocks()
     mocksession.new_config(config)
@@ -806,10 +822,10 @@ def test_run_install_command(newmocksession):
 def test_run_custom_install_command(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         install_command=easy_install {opts} {packages}
-    """,
+        """,
     )
     venv = mocksession.getvenv("python")
     venv.just_created = True
@@ -825,9 +841,9 @@ def test_run_custom_install_command(newmocksession):
 def test_command_relative_issue36(newmocksession, tmpdir, monkeypatch):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
-    """,
+        """,
     )
     x = tmpdir.ensure("x")
     venv = mocksession.getvenv("python")
@@ -846,11 +862,11 @@ def test_command_relative_issue36(newmocksession, tmpdir, monkeypatch):
 def test_ignore_outcome_failing_cmd(newmocksession):
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         commands=testenv_fail
         ignore_outcome=True
-    """,
+        """,
     )
 
     venv = mocksession.getvenv("python")
@@ -877,11 +893,11 @@ def test_tox_testenv_create(newmocksession):
 
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         commands=testenv_fail
         ignore_outcome=True
-    """,
+        """,
         plugins=[Plugin()],
     )
 
@@ -905,10 +921,10 @@ def test_tox_testenv_pre_post(newmocksession):
 
     mocksession = newmocksession(
         [],
-        """
+        """\
         [testenv]
         commands=testenv_fail
-    """,
+        """,
         plugins=[Plugin()],
     )