[Pytest-commit] commit/tox: 2 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Tue Apr 30 16:55:32 CEST 2013


2 new commits in tox:

https://bitbucket.org/hpk42/tox/commits/c57c9607135a/
Changeset:   c57c9607135a
User:        kfekete
Date:        2013-04-27 01:03:59
Summary:     Tests for issue #97 {[section]name} substitution does not work in general
Affected #:  1 file

diff -r 9b7878f71a1e3846c3a36264fcf322d75682ba19 -r c57c9607135ab15517954e92d897f42999dd4c5e tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -176,6 +176,29 @@
         py.test.raises(tox.exception.ConfigError,
             'reader.getdefault("section", "key2")')
 
+    def test_getdefault_other_section_substitution(self, newconfig):
+        config = newconfig("""
+            [section]
+            key = rue
+            [testenv]
+            key = t{[section]key}
+            """)
+        reader = IniReader(config._cfg)
+        x = reader.getdefault("testenv", "key")
+        assert x == "true"
+
+    def test_command_substitution_from_other_section(self, newconfig):
+        config = newconfig("""
+            [section]
+            key = whatever
+            [testenv]
+            commands =
+                echo {[section]key}
+            """)
+        reader = IniReader(config._cfg)
+        x = reader.getargvlist("testenv", "commands")
+        assert x == [["echo", "whatever"]]
+
     def test_argvlist(self, tmpdir, newconfig):
         config = newconfig("""
             [section]


https://bitbucket.org/hpk42/tox/commits/5603e77786d8/
Changeset:   5603e77786d8
User:        kfekete
Date:        2013-04-27 01:04:07
Summary:     Fix issue #97 {[section]name} substitution does not work in general
Affected #:  1 file

diff -r c57c9607135ab15517954e92d897f42999dd4c5e -r 5603e77786d87525364e0006c0cd16fc1654b772 tox/_config.py
--- a/tox/_config.py
+++ b/tox/_config.py
@@ -345,6 +345,9 @@
         self.name = name
         self.url = url
 
+RE_ITEM_REF = re.compile(r'\{(?:(?P<sub_type>[^[:]+):)?(?P<substitution_value>.*)\}')
+# temporary workaround for sublime text syntax highlight bug: ]))'
+
 class IniReader:
     def __init__(self, cfgparser, fallbacksections=None):
         self._cfg = cfgparser
@@ -411,7 +414,6 @@
 
     def _processcommand(self, command):
         posargs = self._subs.get('_posargs', None)
-        pat = r'\{(?:(?P<sub_type>[^:]+):)?(?P<substitution_value>.*)\}'
         words = list(CommandParser(command).words())
         new_command = ''
         for word in words:
@@ -420,9 +422,9 @@
                     new_command += ' '.join(posargs)
                 continue
 
-            new_word = re.sub(pat, self._replace_match, word)
+            new_word = self._replace(word, quote=True)
             # two passes; we might have substitutions in the result
-            new_word = re.sub(pat, self._replace_match, new_word)
+            new_word = self._replace(new_word, quote=True)
             new_command += new_word
 
         return shlex.split(new_command.strip())
@@ -464,38 +466,7 @@
         #print "getdefault", section, name, "returned", repr(x)
         return x
 
-    def _sub(self, match):
-        key = match.group(0)[1:-1]
-        if key.startswith("env:"):
-            envkey = key[4:]
-            if envkey not in os.environ:
-                raise tox.exception.ConfigError(
-                    "substitution %r: %r not found in environment" %
-                    (key, envkey))
-            return os.environ[envkey]
-        val = self._subs.get(key, None)
-        if val is None:
-            if key.startswith("[") and "]" in key:
-                i = key.find("]")
-                section, item = key[1:i], key[i+1:]
-                if section in self._cfg and item in self._cfg[section]:
-                    if (section, item) in self._subststack:
-                        raise ValueError('%s already in %s' %(
-                                (section, item), self._subststack))
-                    x = str(self._cfg[section][item])
-                    self._subststack.append((section, item))
-                    try:
-                        return self._replace(x)
-                    finally:
-                        self._subststack.pop()
-
-            raise tox.exception.ConfigError(
-                "substitution key %r not found" % key)
-        elif py.builtin.callable(val):
-            val = val()
-        return str(val)
-
-    def _replace_posargs(self, match):
+    def _replace_posargs(self, match, quote):
         return self._do_replace_posargs(lambda: match.group('substitution_value'))
 
     def _do_replace_posargs(self, value_func):
@@ -510,7 +481,7 @@
 
         return ''
 
-    def _replace_env(self, match):
+    def _replace_env(self, match, quote):
         envkey = match.group('substitution_value')
         if not envkey:
             raise tox.exception.ConfigError(
@@ -523,21 +494,41 @@
 
         return os.environ[envkey]
 
-    def _replace_substitution(self, match):
+    def _substitute_from_other_section(self, key, quote):
+        if key.startswith("[") and "]" in key:
+            i = key.find("]")
+            section, item = key[1:i], key[i+1:]
+            if section in self._cfg and item in self._cfg[section]:
+                if (section, item) in self._subststack:
+                    raise ValueError('%s already in %s' %(
+                            (section, item), self._subststack))
+                x = str(self._cfg[section][item])
+                self._subststack.append((section, item))
+                try:
+                    return self._replace(x, quote=quote)
+                finally:
+                    self._subststack.pop()
+
+        raise tox.exception.ConfigError(
+            "substitution key %r not found" % key)
+
+    def _replace_substitution(self, match, quote):
         sub_key = match.group('substitution_value')
-        if sub_key not in self._subs:
-            raise tox.exception.ConfigError(
-                "substitution key %r not found" % sub_key)
-        val = self._subs[sub_key]
+        val = self._subs.get(sub_key, None)
+        if val is None:
+            val = self._substitute_from_other_section(sub_key, quote)
         if py.builtin.callable(val):
             val = val()
-        return '"%s"' % str(val).replace('"', r'\"')
+        if quote:
+            return '"%s"' % str(val).replace('"', r'\"')
+        else:
+            return str(val)
 
     def _is_bare_posargs(self, groupdict):
         return groupdict.get('substitution_value', None) == 'posargs' \
                and not groupdict.get('sub_type')
 
-    def _replace_match(self, match):
+    def _replace_match(self, match, quote):
         g = match.groupdict()
 
         # special case: posargs. If there is a 'posargs' substitution value
@@ -560,11 +551,23 @@
         except KeyError:
             raise tox.exception.ConfigError("No support for the %s substitution type" % sub_type)
 
-        return handler(match)
+        # quoting is done in handlers, as at least posargs handling is special:
+        #  all of its arguments are inserted as separate parameters
+        return handler(match, quote)
 
-    def _replace(self, x, rexpattern = re.compile("\{.+?\}")):
+    def _replace_match_quote(self, match):
+        return self._replace_match(match, quote=True)
+    def _replace_match_no_quote(self, match):
+        return self._replace_match(match, quote=False)
+
+    def _replace(self, x, rexpattern=RE_ITEM_REF, quote=False):
+        # XXX is rexpattern used by callers? can it be removed?
         if '{' in x:
-            return rexpattern.sub(self._sub, x)
+            if quote:
+                replace_func = self._replace_match_quote
+            else:
+                replace_func = self._replace_match_no_quote
+            return rexpattern.sub(replace_func, x)
         return x
 
     def _parse_command(self, command):

Repository URL: https://bitbucket.org/hpk42/tox/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the pytest-commit mailing list