diff options
| author | holger krekel <holger@merlinux.eu> | 2014-09-02 14:52:12 +0200 |
|---|---|---|
| committer | holger krekel <holger@merlinux.eu> | 2014-09-02 14:52:12 +0200 |
| commit | 45a0a8507d53fe85c748dbbed8b940ea2ee2d4dd (patch) | |
| tree | 2a76c349dbfe8f5face3975f44d6e3dc209ea780 | |
| parent | c0af5a5eb243d3eb0b4cdd8e452e00838c187010 (diff) | |
| parent | 0a8c4513f6ea3f51b2e8861eae2fbb6faa0a3892 (diff) | |
| download | tox-45a0a8507d53fe85c748dbbed8b940ea2ee2d4dd.tar.gz | |
Merged in myint/tox (pull request #118)
Fix "__PYVENV_LAUNCHER__" problem
| -rw-r--r-- | doc/config.txt | 81 | ||||
| -rw-r--r-- | tests/test_config.py | 28 | ||||
| -rw-r--r-- | tox/_config.py | 14 |
3 files changed, 90 insertions, 33 deletions
diff --git a/doc/config.txt b/doc/config.txt index 0721a87..8ce64db 100644 --- a/doc/config.txt +++ b/doc/config.txt @@ -405,7 +405,7 @@ However, a better approach looks like this:: pytest django15: Django>=1.5,<1.6 django16: Django>=1.6,<1.7 - !py27: unittest2 + py26: unittest2 commands = py.test This uses two new facilities of tox-1.8: @@ -417,6 +417,7 @@ This uses two new facilities of tox-1.8: Let's go through this step by step. + Generative envlist +++++++++++++++++++++++ @@ -432,7 +433,7 @@ like this:: py27-django15 py27-django16 -You can still list environments explicitely along with generated ones:: +You can still list environments explicitly along with generated ones:: envlist = {py26,py27}-django{15,16}, docs, flake @@ -441,13 +442,13 @@ You can still list environments explicitely along with generated ones:: To help with understanding how the variants will produce section values, you can ask tox to show their expansion with a new option:: - $ tox -l - py26-django15 - py26-django16 - py27-django15 - py27-django16 - docs - flake + $ tox -l + py26-django15 + py26-django16 + py27-django15 + py27-django16 + docs + flake Factors and factor-conditional settings @@ -471,23 +472,14 @@ optional lines with unconditional ones:: pytest django15: Django>=1.5,<1.6 django16: Django>=1.6,<1.7 - !py27: unittest2 - -The last line here uses negation of a factor, this means ``unittest2`` will be -in ``deps`` for all pythons except python2.7. The whole effect of this setting -definition could be described with a table: + py26: unittest2 -=============== ================================== -environment deps -=============== ================================== -py26-django15 pytest, Django>=1.5,<1.6, unitest2 -py26-django16 pytest, Django>=1.6,<1.7, unitest2 -py27-django15 pytest, Django>=1.5,<1.6 -py27-django16 pytest, Django>=1.6,<1.7 -=============== ================================== +Reading it line by line: -And this table can significantly grow as you have more dependencies and other -factors such as platform, python version and/or database. +- ``pytest`` will be included unconditionally, +- ``Django>=1.5,<1.6`` will be included for environments containing ``django15`` factor, +- ``Django>=1.6,<1.7`` similarly depends on ``django16`` factor, +- ``unittest`` will be loaded for Python 2.6 environments. .. note:: @@ -496,6 +488,47 @@ factors such as platform, python version and/or database. setting. +Complex factor conditions ++++++++++++++++++++++++++ + +Sometimes you need to specify same line for several factors or create a special +case for a combination of factors. Here is how you do it:: + + [tox] + envlist = py{26,27,33}-django{15,16}-{sqlite,mysql} + + [testenv] + deps = + py33-mysql: PyMySQL ; use if both py33 and mysql are in an env name + py26,py27: urllib3 ; use if any of py26 or py27 are in an env name + py{26,27}-sqlite: mock ; mocking sqlite in python 2.x + +Take a look at first ``deps`` line. It shows how you can special case something +for a combination of factors, you just join combining factors with a hyphen. +This particular line states that ``PyMySQL`` will be loaded for python 3.3, +mysql environments, e.g. ``py33-django15-mysql`` and ``py33-django16-mysql``. + +The second line shows how you use same line for several factors - by listing +them delimited by commas. It's possible to list not only simple factors, but +also their combinations like ``py26-sqlite,py27-sqlite``. + +Finally, factor expressions are expanded the same way as envlist, so last +example could be rewritten as ``py{26,27}-sqlite``. + +.. note:: + + Factors don't do substring matching against env name, instead every + hyphenated expression is split by ``-`` and if ALL the factors in an + expression are also factors of an env then that condition is considered + hold. + + For example, environment ``py26-mysql``: + + - could be matched with expressions ``py26``, ``py26-mysql``, + ``mysql-py26``, + - but not with ``py2`` or ``py26-sql``. + + Other Rules and notes ===================== diff --git a/tests/test_config.py b/tests/test_config.py index 28afa6c..7cbb656 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -835,20 +835,38 @@ class TestConfigTestEnv: def test_factors(self, newconfig): inisource=""" [tox] - envlist = a,b + envlist = a-x,b [testenv] deps= dep-all a: dep-a b: dep-b - !a: dep-not-a + x: dep-x """ conf = newconfig([], inisource) configs = conf.envconfigs - assert [dep.name for dep in configs['a'].deps] == ["dep-all", "dep-a"] - assert [dep.name for dep in configs['b'].deps] == \ - ["dep-all", "dep-b", "dep-not-a"] + assert [dep.name for dep in configs['a-x'].deps] == \ + ["dep-all", "dep-a", "dep-x"] + assert [dep.name for dep in configs['b'].deps] == ["dep-all", "dep-b"] + + def test_factor_ops(self, newconfig): + inisource=""" + [tox] + envlist = {a,b}-{x,y} + + [testenv] + deps= + a,b: dep-a-or-b + a-x: dep-a-and-x + {a,b}-y: dep-ab-and-y + """ + configs = newconfig([], inisource).envconfigs + get_deps = lambda env: [dep.name for dep in configs[env].deps] + assert get_deps("a-x") == ["dep-a-or-b", "dep-a-and-x"] + assert get_deps("a-y") == ["dep-a-or-b", "dep-ab-and-y"] + assert get_deps("b-x") == ["dep-a-or-b"] + assert get_deps("b-y") == ["dep-a-or-b", "dep-ab-and-y"] def test_default_factors(self, newconfig): inisource=""" diff --git a/tox/_config.py b/tox/_config.py index 6e8e706..26603c9 100644 --- a/tox/_config.py +++ b/tox/_config.py @@ -302,7 +302,8 @@ class parseini: factors = set() if section in self._cfg: for _, value in self._cfg[section].items(): - factors.update(re.findall(r'^!?(\w+)\:\s+', value, re.M)) + exprs = re.findall(r'^([\w{},-]+)\:\s+', value, re.M) + factors.update(*mapcat(_split_factor_expr, exprs)) return factors def _makeenvconfig(self, name, section, subs, config): @@ -434,12 +435,17 @@ class parseini: dep2_name = pkg_resources.Requirement.parse(dep2).project_name return dep1_name == dep2_name + def _split_env(env): """if handed a list, action="append" was used for -e """ if not isinstance(env, list): env = [env] return mapcat(_expand_envstr, env) +def _split_factor_expr(expr): + partial_envs = _expand_envstr(expr) + return [set(e.split('-')) for e in partial_envs] + def _expand_envstr(envstr): # split by commas not in groups tokens = re.split(r'(\{[^}]+\})|,', envstr) @@ -628,12 +634,12 @@ class IniReader: def _apply_factors(self, s): def factor_line(line): - m = re.search(r'^(!)?(\w+)\:\s+(.+)', line) + m = re.search(r'^([\w{},-]+)\:\s+(.+)', line) if not m: return line - negate, factor, line = m.groups() - if bool(negate) ^ (factor in self.factors): + expr, line = m.groups() + if any(fs <= self.factors for fs in _split_factor_expr(expr)): return line lines = s.strip().splitlines() |
