Skip to content

Commit c8a8a33

Browse files
committed
feat: add --require-unique-paramset-ids option skips pytest internal logic of id generation
1 parent 462e649 commit c8a8a33

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

changelog/13737.feature.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Added flag --require-unique-paramset-ids to pytest that when set to true will
2+
make pytest raise an exception when non-unique
3+
paramset ids are detected instead of attempting to generate them

src/_pytest/main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ def pytest_addoption(parser: Parser) -> None:
9090
action="store_true",
9191
help="(Deprecated) alias to --strict-markers",
9292
)
93+
group.addoption(
94+
"--require-unique-paramset-ids",
95+
action="store_true",
96+
default=False,
97+
help="Stops pytest automatically generating unique parameter set IDs. "
98+
"and raises an error if there are any duplicates.",
99+
)
93100

94101
group = parser.getgroup("pytest-warnings")
95102
group.addoption(

src/_pytest/python.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,25 @@ def make_unique_parameterset_ids(self) -> list[str | _HiddenParam]:
902902
resolved_ids = list(self._resolve_ids())
903903
# All IDs must be unique!
904904
if len(resolved_ids) != len(set(resolved_ids)):
905+
if self.config and self.config.cache._config.getoption(
906+
"require_unique_paramset_ids"
907+
):
908+
duplicate_indexs = defaultdict(list)
909+
for i, val in enumerate(resolved_ids):
910+
duplicate_indexs[val].append(i)
911+
912+
# Keep only duplicates
913+
duplicates = {k: v for k, v in duplicate_indexs.items() if len(v) > 1}
914+
raise Exception(f"""
915+
Because: require_unique_parameterset_ids is set, pytest won't
916+
attempt to generate unique IDs for parameter sets.
917+
argument values: {self.parametersets}
918+
argument names: {self.argnames}
919+
function name: {self.func_name}
920+
test name: {self.nodeid}
921+
resolved (with non-unique) IDs: {resolved_ids}
922+
duplicates: {duplicates}
923+
""")
905924
# Record the number of occurrences of each ID.
906925
id_counts = Counter(resolved_ids)
907926
# Map the ID to its next suffix.

testing/test_collection.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,3 +2031,34 @@ def test_namespace_packages(pytester: Pytester, import_mode: str):
20312031
" <Function test_module3>",
20322032
]
20332033
)
2034+
2035+
2036+
@pytest.mark.parametrize(
2037+
"parametrize_args, expected_indexs",
2038+
[
2039+
("[1, 1, 3]", "{'1': [[]0, 1[]]}"),
2040+
("[1, 1, 3, 2, 2]", "{'1': [[]0, 1[]], '2': [[]3, 4[]]}"),
2041+
],
2042+
)
2043+
def test_option_parametrize_require_unique_paramset_ids(
2044+
pytester: Pytester, parametrize_args, expected_indexs
2045+
) -> None:
2046+
pytester.makepyfile(
2047+
f"""
2048+
import pytest
2049+
@pytest.mark.parametrize('y', {parametrize_args})
2050+
def test1(y):
2051+
pass
2052+
"""
2053+
)
2054+
result = pytester.runpytest("--require-unique-paramset-ids")
2055+
result.stdout.fnmatch_lines(
2056+
[
2057+
"E*Because: require_unique_parameterset_ids is set, pytest won't",
2058+
"E*attempt to generate unique IDs for parameter sets.",
2059+
"E*argument names: [[]'y'[]]",
2060+
"E*function name: test1",
2061+
"E*test name: test_option_parametrize_require_unique_paramset_ids.py::test1",
2062+
f"E*duplicates: {expected_indexs!s}",
2063+
]
2064+
)

0 commit comments

Comments
 (0)