A few improvements
This commit is contained in:
parent
96be57a3d0
commit
40b2c09ecf
|
@ -14,7 +14,6 @@ from functools import partial
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import cast
|
||||
from typing import Dict
|
||||
from typing import final
|
||||
from typing import Generator
|
||||
|
@ -498,8 +497,11 @@ class PyCollector(PyobjMixin, nodes.Collector):
|
|||
if not metafunc._calls:
|
||||
yield Function.from_parent(self, name=name, fixtureinfo=fixtureinfo)
|
||||
else:
|
||||
# Dynamic direct parametrization may have shadowed some fixtures,
|
||||
# so make sure we update what the function really needs.
|
||||
# Direct parametrizations taking place in module/class-specific
|
||||
# `metafunc.parametrize` calls may have shadowed some fixtures, so make sure
|
||||
# we update what the function really needs a.k.a its fixture closure. Note that
|
||||
# direct parametrizations using `@pytest.mark.parametrize` have already been considered
|
||||
# into making the closure using `ignore_args` arg to `getfixtureclosure`.
|
||||
fixtureinfo.prune_dependency_tree()
|
||||
|
||||
for callspec in metafunc._calls:
|
||||
|
@ -1170,7 +1172,7 @@ def get_direct_param_fixture_func(request: FixtureRequest) -> Any:
|
|||
return request.param
|
||||
|
||||
|
||||
# Used for storing artificial fixturedefs for direct parametrization.
|
||||
# Used for storing pseudo fixturedefs for direct parametrization.
|
||||
name2pseudofixturedef_key = StashKey[Dict[str, FixtureDef[Any]]]()
|
||||
|
||||
|
||||
|
@ -1330,8 +1332,8 @@ class Metafunc:
|
|||
object.__setattr__(_param_mark._param_ids_from, "_param_ids_generated", ids)
|
||||
|
||||
# Add funcargs as fixturedefs to fixtureinfo.arg2fixturedefs by registering
|
||||
# artificial FixtureDef's so that later at test execution time we can rely
|
||||
# on a proper FixtureDef to exist for fixture setup.
|
||||
# artificial "pseudo" FixtureDef's so that later at test execution time we can
|
||||
# rely on a proper FixtureDef to exist for fixture setup.
|
||||
arg2fixturedefs = self._arg2fixturedefs
|
||||
node = None
|
||||
# If we have a scope that is higher than function, we need
|
||||
|
@ -1339,7 +1341,8 @@ class Metafunc:
|
|||
# a per-scope basis. We thus store and cache the fixturedef on the
|
||||
# node related to the scope.
|
||||
if scope_ is not Scope.Function:
|
||||
collector = cast(nodes.Node, self.definition.parent)
|
||||
collector = self.definition.parent
|
||||
assert collector is not None
|
||||
node = get_scope_node(collector, scope_)
|
||||
if node is None:
|
||||
# If used class scope and there is no class, use module-level
|
||||
|
|
|
@ -23,6 +23,7 @@ from _pytest.compat import getfuncargnames
|
|||
from _pytest.compat import NOTSET
|
||||
from _pytest.outcomes import fail
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.python import Function
|
||||
from _pytest.python import IdMaker
|
||||
from _pytest.scope import Scope
|
||||
|
||||
|
@ -974,16 +975,6 @@ class TestMetafunc:
|
|||
assert metafunc._calls[1].params == dict(x=3, y=4)
|
||||
assert metafunc._calls[1].id == "3-4"
|
||||
|
||||
@pytest.mark.xfail(reason="Will pass upon merging PR#11257")
|
||||
def test_parametrize_with_duplicate_values(self) -> None:
|
||||
metafunc = self.Metafunc(lambda x, y: None)
|
||||
metafunc.parametrize(("x", "y"), [(1, 2), (3, 4), (1, 5), (2, 2)])
|
||||
assert len(metafunc._calls) == 4
|
||||
assert metafunc._calls[0].indices == dict(x=0, y=0)
|
||||
assert metafunc._calls[1].indices == dict(x=1, y=1)
|
||||
assert metafunc._calls[2].indices == dict(x=0, y=2)
|
||||
assert metafunc._calls[3].indices == dict(x=2, y=0)
|
||||
|
||||
def test_high_scoped_parametrize_reordering(self, pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
|
@ -1018,36 +1009,6 @@ class TestMetafunc:
|
|||
]
|
||||
)
|
||||
|
||||
@pytest.mark.xfail(reason="Will pass upon merging PR#11257")
|
||||
def test_high_scoped_parametrize_with_duplicate_values_reordering(
|
||||
self, pytester: Pytester
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def fixture1(request):
|
||||
pass
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def fixture2(request):
|
||||
pass
|
||||
|
||||
@pytest.mark.parametrize("fixture1, fixture2", [("a", 0), ("b", 1), ("a", 2)], indirect=True)
|
||||
def test(fixture1, fixture2):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
result = pytester.runpytest("--collect-only")
|
||||
result.stdout.re_match_lines(
|
||||
[
|
||||
r" <Function test\[a-0\]>",
|
||||
r" <Function test\[a-2\]>",
|
||||
r" <Function test\[b-1\]>",
|
||||
]
|
||||
)
|
||||
|
||||
def test_parametrize_multiple_times(self, pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
|
@ -1590,29 +1551,27 @@ class TestMetafuncFunctional:
|
|||
def test_parametrize_module_level_test_with_class_scope(
|
||||
self, pytester: Pytester
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
module = pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def item(request):
|
||||
return request._pyfuncitem
|
||||
|
||||
fixturedef = None
|
||||
|
||||
@pytest.mark.parametrize("x", [0, 1], scope="class")
|
||||
def test_1(item, x):
|
||||
global fixturedef
|
||||
fixturedef = item._fixtureinfo.name2fixturedefs['x'][-1]
|
||||
def test_1(x):
|
||||
pass
|
||||
|
||||
@pytest.mark.parametrize("x", [1, 2], scope="module")
|
||||
def test_2(item, x):
|
||||
global fixturedef
|
||||
assert fixturedef == item._fixtureinfo.name2fixturedefs['x'][-1]
|
||||
def test_2(x):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
result = pytester.runpytest()
|
||||
assert result.ret == 0
|
||||
test_1_0, _, test_2_0, _ = pytester.genitems((pytester.getmodulecol(module),))
|
||||
test_1_fixture_x = cast(Function, test_1_0)._fixtureinfo.name2fixturedefs["x"][
|
||||
-1
|
||||
]
|
||||
test_2_fixture_x = cast(Function, test_2_0)._fixtureinfo.name2fixturedefs["x"][
|
||||
-1
|
||||
]
|
||||
assert test_1_fixture_x == test_2_fixture_x
|
||||
|
||||
|
||||
class TestMetafuncFunctionalAuto:
|
||||
|
|
Loading…
Reference in New Issue