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 <zac.hatfield.dodds@gmail.com>
This commit is contained in:
parent
54623f0f33
commit
af9b1dcc24
1
AUTHORS
1
AUTHORS
|
@ -367,6 +367,7 @@ Tadek Teleżyński
|
||||||
Takafumi Arakaki
|
Takafumi Arakaki
|
||||||
Taneli Hukkinen
|
Taneli Hukkinen
|
||||||
Tanvi Mehta
|
Tanvi Mehta
|
||||||
|
Tanya Agarwal
|
||||||
Tarcisio Fischer
|
Tarcisio Fischer
|
||||||
Tareq Alayan
|
Tareq Alayan
|
||||||
Tatiana Ovary
|
Tatiana Ovary
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Parametrized tests now *really do* ensure that the ids given to each input are unique - for
|
||||||
|
example, ``a, a, a0`` now results in ``a1, a2, a0`` instead of the previous (buggy) ``a0, a1, a0``.
|
||||||
|
This necessarily means changing nodeids where these were previously colliding, and for
|
||||||
|
readability adds an underscore when non-unique ids end in a number.
|
|
@ -1002,8 +1002,18 @@ class IdMaker:
|
||||||
# Suffix non-unique IDs to make them unique.
|
# Suffix non-unique IDs to make them unique.
|
||||||
for index, id in enumerate(resolved_ids):
|
for index, id in enumerate(resolved_ids):
|
||||||
if id_counts[id] > 1:
|
if id_counts[id] > 1:
|
||||||
resolved_ids[index] = f"{id}{id_suffixes[id]}"
|
suffix = ""
|
||||||
|
if id[-1].isdigit():
|
||||||
|
suffix = "_"
|
||||||
|
new_id = f"{id}{suffix}{id_suffixes[id]}"
|
||||||
|
while new_id in set(resolved_ids):
|
||||||
|
id_suffixes[id] += 1
|
||||||
|
new_id = f"{id}{suffix}{id_suffixes[id]}"
|
||||||
|
resolved_ids[index] = new_id
|
||||||
id_suffixes[id] += 1
|
id_suffixes[id] += 1
|
||||||
|
assert len(resolved_ids) == len(
|
||||||
|
set(resolved_ids)
|
||||||
|
), f"Internal error: {resolved_ids=}"
|
||||||
return resolved_ids
|
return resolved_ids
|
||||||
|
|
||||||
def _resolve_ids(self) -> Iterable[str]:
|
def _resolve_ids(self) -> Iterable[str]:
|
||||||
|
|
|
@ -341,6 +341,45 @@ class TestGeneralUsage:
|
||||||
assert res.ret == 0
|
assert res.ret == 0
|
||||||
res.stdout.fnmatch_lines(["*1 passed*"])
|
res.stdout.fnmatch_lines(["*1 passed*"])
|
||||||
|
|
||||||
|
def test_direct_addressing_selects_duplicates(self, pytester: Pytester) -> None:
|
||||||
|
p = pytester.makepyfile(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("a", [1, 2, 10, 11, 2, 1, 12, 11])
|
||||||
|
def test_func(a):
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest(p)
|
||||||
|
result.assert_outcomes(failed=0, passed=8)
|
||||||
|
|
||||||
|
def test_direct_addressing_selects_duplicates_1(self, pytester: Pytester) -> None:
|
||||||
|
p = pytester.makepyfile(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("a", [1, 2, 10, 11, 2, 1, 12, 1_1,2_1])
|
||||||
|
def test_func(a):
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest(p)
|
||||||
|
result.assert_outcomes(failed=0, passed=9)
|
||||||
|
|
||||||
|
def test_direct_addressing_selects_duplicates_2(self, pytester: Pytester) -> None:
|
||||||
|
p = pytester.makepyfile(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("a", ["a","b","c","a","a1"])
|
||||||
|
def test_func(a):
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest(p)
|
||||||
|
result.assert_outcomes(failed=0, passed=5)
|
||||||
|
|
||||||
def test_direct_addressing_notfound(self, pytester: Pytester) -> None:
|
def test_direct_addressing_notfound(self, pytester: Pytester) -> None:
|
||||||
p = pytester.makepyfile(
|
p = pytester.makepyfile(
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue