Skip to content

Commit adcdeb9

Browse files
committed
fixtures: fix incorrect "duplicate parametrization" when using indirect=[...]
The code in `_get_direct_parametrize_args` only handled `indirect=True/False`, it didn't account for `indirect=[...]`. This caused the added test to start failing after d56b1af. Fix by using the common `_resolve_args_directness` function. It's a bit heavy for the task but correctness first... Fix #13974.
1 parent 3aabdca commit adcdeb9

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

src/_pytest/fixtures.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,11 +1523,16 @@ def _get_direct_parametrize_args(node: nodes.Node) -> set[str]:
15231523
"""
15241524
parametrize_argnames: set[str] = set()
15251525
for marker in node.iter_markers(name="parametrize"):
1526-
if not marker.kwargs.get("indirect", False):
1527-
p_argnames, _ = ParameterSet._parse_parametrize_args(
1528-
*marker.args, **marker.kwargs
1529-
)
1530-
parametrize_argnames.update(p_argnames)
1526+
indirect = marker.kwargs.get("indirect", False)
1527+
p_argnames, _ = ParameterSet._parse_parametrize_args(
1528+
*marker.args, **marker.kwargs
1529+
)
1530+
p_directness = _resolve_args_directness(p_argnames, indirect, node.nodeid)
1531+
parametrize_argnames.update(
1532+
argname
1533+
for argname, directness in p_directness.items()
1534+
if directness == "direct"
1535+
)
15311536
return parametrize_argnames
15321537

15331538

testing/python/collect.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,42 @@ def test_overridden_via_param(value):
524524
rec = pytester.inline_run()
525525
rec.assertoutcome(passed=1)
526526

527+
def test_parametrize_overrides_parametrized_fixture_with_unrelated_indirect(
528+
self, pytester: Pytester
529+
) -> None:
530+
"""Test parametrization when parameter overrides existing parametrized fixture with same name,
531+
and there is an unrelated indirect param.
532+
533+
Regression test for #13974.
534+
"""
535+
pytester.makepyfile(
536+
"""
537+
import pytest
538+
539+
@pytest.fixture(params=["a", "b"])
540+
def target(request):
541+
return request.param
542+
543+
@pytest.fixture
544+
def val(request):
545+
return int(request.param)
546+
547+
@pytest.mark.parametrize(
548+
["val", "target"],
549+
[
550+
("1", 1),
551+
("2", 2),
552+
],
553+
indirect=["val"],
554+
)
555+
def test(val, target):
556+
assert val == target
557+
"""
558+
)
559+
result = pytester.runpytest()
560+
assert result.ret == 0
561+
result.assert_outcomes(passed=2)
562+
527563
def test_parametrize_overrides_indirect_dependency_fixture(
528564
self, pytester: Pytester
529565
) -> None:

0 commit comments

Comments
 (0)