From af362b311d4cc1391726937d475284b8d6ef4e7c Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Mon, 25 Jul 2016 10:54:02 +0200 Subject: [PATCH] Fixed scope override inside metafunc.parametrize. Fixes #634 --- AUTHORS | 1 + CHANGELOG.rst | 5 +++++ _pytest/python.py | 10 ++++++++-- testing/python/metafunc.py | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4ce6f0aa46e..7ef2df84acb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,6 +35,7 @@ David Díaz-Barquero David Mohr David Vierra Diego Russo +Dmitry Dygalo Edison Gustavo Muenz Eduardo Schettino Elizaveta Shashkova diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5cdb63470f1..e66bee59608 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -51,6 +51,10 @@ * ImportErrors in plugins now are a fatal error instead of issuing a pytest warning (`#1479`_). Thanks to `@The-Compiler`_ for the PR. +* Fixed scope override inside metafunc.parametrize (`#634`_). + Thanks to `Stranger6667`_ for the PR. + +.. _#634: https://github.com/pytest-dev/pytest/issues/634 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 .. _#1597: https://github.com/pytest-dev/pytest/pull/1597 @@ -72,6 +76,7 @@ .. _@DRMacIver: https://github.com/DRMacIver .. _@BeyondEvil: https://github.com/BeyondEvil .. _@JonathonSonesen: https://github.com/JonathonSonesen +.. _@Stranger6667: https://github.com/Stranger6667 2.9.2 diff --git a/_pytest/python.py b/_pytest/python.py index 6242fd49782..dd64c8049bf 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -998,9 +998,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