From 3eb7efaa615c7402beecf1c188574cad72422c6d Mon Sep 17 00:00:00 2001 From: barneygale Date: Wed, 5 Jun 2019 17:23:31 +0100 Subject: [PATCH 1/2] Use POSIX shell rules for creating posargs string on non-Windows platforms. Closes #1336 --- CONTRIBUTORS | 1 + docs/changelog/1336.bugfix.rst | 2 ++ src/tox/config/__init__.py | 10 +++++++++- tests/unit/config/test_config.py | 12 +++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 docs/changelog/1336.bugfix.rst diff --git a/CONTRIBUTORS b/CONTRIBUTORS index a95197ffb..39d848b4f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -8,6 +8,7 @@ Anthon van der Neuth Anthony Sottile Ashley Whetter Asmund Grammeltwedt +Barney Gale Barry Warsaw Bartolome Sanchez Salado Benoit Pierre diff --git a/docs/changelog/1336.bugfix.rst b/docs/changelog/1336.bugfix.rst new file mode 100644 index 000000000..17f9dd556 --- /dev/null +++ b/docs/changelog/1336.bugfix.rst @@ -0,0 +1,2 @@ +tox used Windows shell rules on non-Windows platforms when transforming +positional arguments to a string - by :user:`barneygale`. diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py index 19820d033..602fab818 100644 --- a/src/tox/config/__init__.py +++ b/src/tox/config/__init__.py @@ -15,6 +15,11 @@ from subprocess import list2cmdline from threading import Thread +try: + from shlex import quote as shlex_quote +except ImportError: + from pipes import quote as shlex_quote + import importlib_metadata import pluggy import py @@ -1674,7 +1679,10 @@ def getargvlist(cls, reader, value, replace=True): @classmethod def processcommand(cls, reader, command, replace=True): posargs = getattr(reader, "posargs", "") - posargs_string = list2cmdline([x for x in posargs if x]) + if sys.platform.startswith("win"): + posargs_string = list2cmdline([x for x in posargs if x]) + else: + posargs_string = " ".join([shlex_quote(x) for x in posargs if x]) # Iterate through each word of the command substituting as # appropriate to construct the new command string. This diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index 7c1fa6045..2f019b791 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -730,8 +730,18 @@ def test_argvlist_posargs_with_quotes(self, newconfig): cmd1 -f {posargs} """ ) + # The operating system APIs for launching processes differ between + # Windows and other OSs. On Windows, the command line is passed as a + # string (and not a list of strings). Python uses the MS C runtime + # rules for splitting this string into `sys.argv`, and those rules + # differ from POSIX shell rules in their treatment of quoted arguments. + if sys.platform.startswith("win"): + substitutions = ["foo", "'bar", "baz'"] + else: + substitutions = ["foo", "bar baz"] + reader = SectionReader("section", config._cfg) - reader.addsubstitutions(["foo", "'bar", "baz'"]) + reader.addsubstitutions(substitutions) assert reader.getargvlist("key1") == [] x = reader.getargvlist("key2") assert x == [["cmd1", "-f", "foo", "bar baz"]] From d5cfac5414d02d9555c4911326b9309d6dc337a6 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 5 Jun 2019 09:59:05 -0700 Subject: [PATCH 2/2] pre-commit run --all-files --- src/tox/config/__init__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py index 602fab818..4437268e3 100644 --- a/src/tox/config/__init__.py +++ b/src/tox/config/__init__.py @@ -15,11 +15,6 @@ from subprocess import list2cmdline from threading import Thread -try: - from shlex import quote as shlex_quote -except ImportError: - from pipes import quote as shlex_quote - import importlib_metadata import pluggy import py @@ -44,6 +39,12 @@ from .parallel import add_parallel_config, add_parallel_flags from .reporter import add_verbosity_commands +try: + from shlex import quote as shlex_quote +except ImportError: + from pipes import quote as shlex_quote + + hookimpl = tox.hookimpl """DEPRECATED - REMOVE - this is left for compatibility with plugins importing this from here.