Skip to content

Commit af9b1dc

Browse files
TanyaAgarwal28pre-commit-ci[bot]Zac-HD
authored
Duplicated parameters in parametrize marker (#11489)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Zac Hatfield-Dodds <[email protected]>
1 parent 54623f0 commit af9b1dc

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ Tadek Teleżyński
367367
Takafumi Arakaki
368368
Taneli Hukkinen
369369
Tanvi Mehta
370+
Tanya Agarwal
370371
Tarcisio Fischer
371372
Tareq Alayan
372373
Tatiana Ovary

changelog/11456.bugfix.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Parametrized tests now *really do* ensure that the ids given to each input are unique - for
2+
example, ``a, a, a0`` now results in ``a1, a2, a0`` instead of the previous (buggy) ``a0, a1, a0``.
3+
This necessarily means changing nodeids where these were previously colliding, and for
4+
readability adds an underscore when non-unique ids end in a number.

src/_pytest/python.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,8 +1002,18 @@ def make_unique_parameterset_ids(self) -> List[str]:
10021002
# Suffix non-unique IDs to make them unique.
10031003
for index, id in enumerate(resolved_ids):
10041004
if id_counts[id] > 1:
1005-
resolved_ids[index] = f"{id}{id_suffixes[id]}"
1005+
suffix = ""
1006+
if id[-1].isdigit():
1007+
suffix = "_"
1008+
new_id = f"{id}{suffix}{id_suffixes[id]}"
1009+
while new_id in set(resolved_ids):
1010+
id_suffixes[id] += 1
1011+
new_id = f"{id}{suffix}{id_suffixes[id]}"
1012+
resolved_ids[index] = new_id
10061013
id_suffixes[id] += 1
1014+
assert len(resolved_ids) == len(
1015+
set(resolved_ids)
1016+
), f"Internal error: {resolved_ids=}"
10071017
return resolved_ids
10081018

10091019
def _resolve_ids(self) -> Iterable[str]:

testing/acceptance_test.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,45 @@ def test_func(i):
341341
assert res.ret == 0
342342
res.stdout.fnmatch_lines(["*1 passed*"])
343343

344+
def test_direct_addressing_selects_duplicates(self, pytester: Pytester) -> None:
345+
p = pytester.makepyfile(
346+
"""
347+
import pytest
348+
349+
@pytest.mark.parametrize("a", [1, 2, 10, 11, 2, 1, 12, 11])
350+
def test_func(a):
351+
pass
352+
"""
353+
)
354+
result = pytester.runpytest(p)
355+
result.assert_outcomes(failed=0, passed=8)
356+
357+
def test_direct_addressing_selects_duplicates_1(self, pytester: Pytester) -> None:
358+
p = pytester.makepyfile(
359+
"""
360+
import pytest
361+
362+
@pytest.mark.parametrize("a", [1, 2, 10, 11, 2, 1, 12, 1_1,2_1])
363+
def test_func(a):
364+
pass
365+
"""
366+
)
367+
result = pytester.runpytest(p)
368+
result.assert_outcomes(failed=0, passed=9)
369+
370+
def test_direct_addressing_selects_duplicates_2(self, pytester: Pytester) -> None:
371+
p = pytester.makepyfile(
372+
"""
373+
import pytest
374+
375+
@pytest.mark.parametrize("a", ["a","b","c","a","a1"])
376+
def test_func(a):
377+
pass
378+
"""
379+
)
380+
result = pytester.runpytest(p)
381+
result.assert_outcomes(failed=0, passed=5)
382+
344383
def test_direct_addressing_notfound(self, pytester: Pytester) -> None:
345384
p = pytester.makepyfile(
346385
"""

0 commit comments

Comments
 (0)