diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c9994794373..164fe18b6fc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -54,6 +54,10 @@ * Fixed collection of classes with custom ``__new__`` method. Fixes `#1579`_. Thanks to `@Stranger6667`_ for the PR. +* Fixed scope overriding inside metafunc.parametrize (`#634`_). + Thanks to `@Stranger6667`_ for the PR. + +.. _#634: https://github.com/pytest-dev/pytest/issues/634 .. _#1579: https://github.com/pytest-dev/pytest/issues/1579 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 diff --git a/_pytest/python.py b/_pytest/python.py index 812adf4b457..693d7c8c5d1 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1005,9 +1005,15 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None, newmarks = newkeywords.setdefault(0, {}) newmarks[newmark.markname] = newmark - if scope is None: - scope = "function" + if self._arg2fixturedefs: + # Takes the most narrow scope from used fixtures + fixtures_scopes = [fixturedef[0].scope for fixturedef in self._arg2fixturedefs.values()] + for scope in reversed(scopes): + if scope in fixtures_scopes: + break + else: + scope = 'function' scopenum = scopes.index(scope) valtypes = {} for arg in argnames: diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 13c70957943..d6e45384d91 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -819,6 +819,43 @@ def test_checklength(): reprec = testdir.inline_run() reprec.assertoutcome(passed=5) + def test_parametrize_issue634(self, testdir): + testdir.makepyfile(''' + import pytest + + @pytest.fixture(scope='module') + def foo(request): + print('preparing foo-%d' % request.param) + return 'foo-%d' % request.param + + + def test_one(foo): + pass + + + def test_two(foo): + pass + + + test_two.test_with = (2, 3) + + + def pytest_generate_tests(metafunc): + params = (1, 2, 3, 4) + if not 'foo' in metafunc.fixturenames: + return + + test_with = getattr(metafunc.function, 'test_with', None) + if test_with: + params = test_with + metafunc.parametrize('foo', params, indirect=True) + + ''') + result = testdir.runpytest("-s") + output = result.stdout.str() + assert output.count('preparing foo-2') == 1 + assert output.count('preparing foo-3') == 1 + def test_parametrize_issue323(self, testdir): testdir.makepyfile(""" import pytest