diff --git a/python-tox-Fix-command-expansion-and-parsing.patch b/python-tox-Fix-command-expansion-and-parsing.patch new file mode 100644 index 0000000..c5450cc --- /dev/null +++ b/python-tox-Fix-command-expansion-and-parsing.patch @@ -0,0 +1,93 @@ +# HG changeset patch +# User Clark Boylan +# Date 1391830704 28800 +# Node ID 62fe57a8fd3f8f44be8957e59846387d2f505227 +# Parent b0360a54ab368ef428c7f83601ba6b64f6fec64f +Fix command expansion and parsing. + +Tox testenv commands are parsed to expand variable substitutions and +construct the argv list that will be passed to exec. Prior to this +commit this parsing ate quotes surrounding variables and treated +multiword variables as single argv items. Neither behavior was correct. +To fix this create the expanded command before handing it off to shlex +to do the tokenization of the argv list. Doing the parsing in this +order ensures it is correct. + +diff --git a/tests/test_config.py b/tests/test_config.py +--- a/tests/test_config.py ++++ b/tests/test_config.py +@@ -278,7 +278,7 @@ + # "reader.getargvlist('section', 'key1')") + assert reader.getargvlist('section', 'key1') == [] + x = reader.getargvlist("section", "key2") +- assert x == [["cmd1", "with space", "grr"], ++ assert x == [["cmd1", "with", "space", "grr"], + ["cmd2", "grr"]] + + def test_argvlist_windows_escaping(self, tmpdir, newconfig): +@@ -304,7 +304,7 @@ + # "reader.getargvlist('section', 'key1')") + assert reader.getargvlist('section', 'key1') == [] + x = reader.getargvlist("section", "key2") +- assert x == [["cmd1", "with space", "grr"]] ++ assert x == [["cmd1", "with", "space", "grr"]] + + + def test_argvlist_quoting_in_command(self, tmpdir, newconfig): +diff --git a/tox/_config.py b/tox/_config.py +--- a/tox/_config.py ++++ b/tox/_config.py +@@ -527,30 +527,35 @@ + def _processcommand(self, command): + posargs = getattr(self, "posargs", None) + +- # special treat posargs which might contain multiple arguments +- # in their defaults ++ # 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. + newcommand = "" + for word in CommandParser(command).words(): +- if word.startswith("{posargs:") and word.endswith("}"): ++ if word == "{posargs}" or word == "[]": + if posargs: +- word = "{posargs}" ++ newcommand += " ".join(posargs) ++ continue ++ elif word.startswith("{posargs:") and word.endswith("}"): ++ if posargs: ++ newcommand += " ".join(posargs) ++ continue + else: + word = word[9:-1] +- newcommand += word ++ new_arg = "" ++ new_word = self._replace(word) ++ new_word = self._replace(new_word) ++ new_arg += new_word ++ newcommand += new_arg + +- # now we can properly parse the command +- argv = [] +- for arg in shlex.split(newcommand): +- if arg in ('[]', "{posargs}"): +- if posargs: +- argv.extend(posargs) +- continue +- new_arg = "" +- for word in CommandParser(arg).words(): +- new_word = self._replace(word) +- new_word = self._replace(new_word) +- new_arg += new_word +- argv.append(new_arg) ++ # 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 = '' ++ shlexer.commenters = '' ++ argv = list(shlexer) + return argv + + def getargv(self, section, name, default=None, replace=True): diff --git a/python-tox.spec b/python-tox.spec index 5d14301..1647f97 100644 --- a/python-tox.spec +++ b/python-tox.spec @@ -12,7 +12,7 @@ %global pypiname tox Name: python-tox Version: 1.7.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Virtualenv-based automation of test activities # file toxbootstrap.py is licensed under MIT License @@ -20,6 +20,8 @@ License: GPLv2+ and MIT URL: http://codespeak.net/tox Source0: http://pypi.python.org/packages/source/t/%{pypiname}/%{pypiname}-%{version}.tar.gz +Patch0: python-tox-Fix-command-expansion-and-parsing.patch + BuildArch: noarch BuildRequires: python2-devel BuildRequires: python-setuptools @@ -66,6 +68,8 @@ can use for: %prep %setup -q -n %{pypiname}-%{version} +%patch0 -p1 + %if 0%{?with_python3} rm -rf %{py3dir} cp -a . %{py3dir} @@ -120,6 +124,10 @@ TOXENV=py27 %{__python} setup.py test %changelog +* Wed Aug 13 2014 Matthias Runge - 1.7.1-3 +- Fix ConfigError: ConfigError: substitution key 'posargs' not found + (rhbz#1127961, rhbz#1128562) + * Wed Jul 30 2014 Matthias Runge - 1.7.1-2 - require virtualenv >= 1.11.2 (rhbz#1122603)