From 8f2691c436e323297ef7c1e005b51bc50868b463 Mon Sep 17 00:00:00 2001 From: Bartolome Sanchez Date: Fri, 2 Mar 2018 17:55:50 +0100 Subject: [PATCH] Fix bug with incorrectly defactorized dependencies https://github.com/tox-dev/tox/issues/706 By performing dependencies replacement before applying factors, since previously this function was being incorrectly called with unrolled dependencies. --- tests/test_config.py | 31 ++++++++++++++++++++++++++++++- tox/config.py | 9 +++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 26421fa50..61d106bfe 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1294,7 +1294,36 @@ def test_take_dependencies_from_other_testenv( ) conf = newconfig([], inisource).envconfigs['py27'] packages = [dep.name for dep in conf.deps] - assert packages == list(deps) + ['fun', 'frob>1.0,<2.0'] + assert packages == ['pytest', 'pytest-cov', 'fun', 'frob>1.0,<2.0'] + + # https://github.com/tox-dev/tox/issues/706 + @pytest.mark.parametrize('envlist', [['py27', 'coverage', 'other']]) + def test_regression_test_issue_706(self, newconfig, envlist): + inisource = """ + [tox] + envlist = {envlist} + [testenv] + deps= + flake8 + coverage: coverage + [testenv:py27] + deps= + {{[testenv]deps}} + fun + """.format( + envlist=','.join(envlist), + ) + conf = newconfig([], inisource).envconfigs['coverage'] + packages = [dep.name for dep in conf.deps] + assert packages == ['flake8', 'coverage'] + + conf = newconfig([], inisource).envconfigs['other'] + packages = [dep.name for dep in conf.deps] + assert packages == ['flake8'] + + conf = newconfig([], inisource).envconfigs['py27'] + packages = [dep.name for dep in conf.deps] + assert packages == ['flake8', 'fun'] def test_take_dependencies_from_other_section(self, newconfig): inisource = """ diff --git a/tox/config.py b/tox/config.py index ad72bdf30..f8cb9ff47 100755 --- a/tox/config.py +++ b/tox/config.py @@ -1076,10 +1076,10 @@ def getstring(self, name, default=None, replace=True, crossonly=False): if x is None: x = default else: + x = self._replace_if_needed(x, name, replace, crossonly) x = self._apply_factors(x) - if replace and x and hasattr(x, 'replace'): - x = self._replace(x, name=name, crossonly=crossonly) + x = self._replace_if_needed(x, name, replace, crossonly) # print "getstring", self.section_name, name, "returned", repr(x) return x @@ -1115,6 +1115,11 @@ def _replace(self, value, name=None, section_name=None, crossonly=False): raise return replaced + def _replace_if_needed(self, x, name, replace, crossonly): + if replace and x and hasattr(x, 'replace'): + x = self._replace(x, name=name, crossonly=crossonly) + return x + class Replacer: RE_ITEM_REF = re.compile(