Skip to content

Commit b4df2b3

Browse files
Enforces having unique test ids in a single namespace (#11687)
I found lots of duplicate test names. It might hide important errors, be hard to reproduce or rerun. Refs #11662 Co-authored-by: Shantanu <[email protected]>
1 parent 9e34f6a commit b4df2b3

27 files changed

+48
-40
lines changed

mypy/test/data.py

+8
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,13 @@ def split_test_cases(parent: 'DataFileCollector', suite: 'DataSuite',
578578
data,
579579
flags=re.DOTALL | re.MULTILINE)
580580
line_no = cases[0].count('\n') + 1
581+
test_names = set()
581582
for i in range(1, len(cases), NUM_GROUPS):
582583
name, writescache, only_when, platform_flag, skip, xfail, data = cases[i:i + NUM_GROUPS]
584+
if name in test_names:
585+
raise RuntimeError('Found a duplicate test name "{}" in {} on line {}'.format(
586+
name, parent.name, line_no,
587+
))
583588
platform = platform_flag[1:] if platform_flag else None
584589
yield DataDrivenTestCase.from_parent(
585590
parent=parent,
@@ -596,6 +601,9 @@ def split_test_cases(parent: 'DataFileCollector', suite: 'DataSuite',
596601
)
597602
line_no += data.count('\n') + 1
598603

604+
# Record existing tests to prevent duplicates:
605+
test_names.update({name})
606+
599607

600608
class DataSuiteCollector(pytest.Class):
601609
def collect(self) -> Iterator['DataFileCollector']:

test-data/unit/check-abstract.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ a.f(B()) # E: No overload variant of "f" of "A" matches argument type "B" \
600600
# N: def f(self, x: int) -> int \
601601
# N: def f(self, x: str) -> str
602602

603-
[case testOverloadedAbstractMethodVariantMissingDecorator1]
603+
[case testOverloadedAbstractMethodVariantMissingDecorator0]
604604
from foo import *
605605
[file foo.pyi]
606606
from abc import abstractmethod, ABCMeta

test-data/unit/check-attr.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ reveal_type(sub_str.attr) # N: Revealed type is "builtins.str*"
502502
[builtins fixtures/bool.pyi]
503503

504504

505-
[case testAttrsGenericInheritance]
505+
[case testAttrsGenericInheritance2]
506506
from typing import Generic, TypeVar
507507
import attr
508508

test-data/unit/check-class-namedtuple.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ a = A(B())
270270
a = A(1) # E: Argument 1 to "A" has incompatible type "int"; expected "B"
271271
[builtins fixtures/tuple.pyi]
272272

273-
[case testNewNamedTupleProperty]
273+
[case testNewNamedTupleProperty36]
274274
# flags: --python-version 3.6
275275
from typing import NamedTuple
276276

test-data/unit/check-classes.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -6463,7 +6463,7 @@ class C(B):
64636463
[out]
64646464
main:4: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int")
64656465

6466-
[case testIgnorePrivateMethodsTypeCheck]
6466+
[case testIgnorePrivateMethodsTypeCheck2]
64676467
class A:
64686468
def __foo_(self) -> int: ...
64696469
class B:

test-data/unit/check-functions.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ x = None # type: Any
14851485
if x:
14861486
def f(x: int) -> None: pass # E: All conditional function variants must have identical signatures
14871487

1488-
[case testConditionalRedefinitionOfAnUnconditionalFunctionDefinition1]
1488+
[case testConditionalRedefinitionOfAnUnconditionalFunctionDefinition2]
14891489
from typing import Any
14901490
def f(x: int) -> None: pass # N: "f" defined here
14911491
x = None # type: Any
@@ -2212,7 +2212,7 @@ from typing import Callable
22122212
class A:
22132213
def f(self) -> None:
22142214
# In particular, test that the error message contains "g" of "A".
2215-
self.g() # E: Too few arguments for "g" of "A"
2215+
self.g() # E: Too few arguments for "g" of "A"
22162216
self.g(1)
22172217
@dec
22182218
def g(self, x: str) -> None: pass

test-data/unit/check-generics.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class C: pass
5252
[out]
5353
main:8: error: Incompatible types in assignment (expression has type "C", variable has type "B")
5454

55-
[case testGenericMemberVariable]
55+
[case testGenericMemberVariable2]
5656
from typing import TypeVar, Generic
5757
T = TypeVar('T')
5858
a, b, c = None, None, None # type: (A[B], B, C)
@@ -2118,7 +2118,7 @@ class B(A[T], Generic[T, S]):
21182118
reveal_type(B.foo) # N: Revealed type is "def [T, S] () -> Tuple[T`1, __main__.B[T`1, S`2]]"
21192119
[builtins fixtures/classmethod.pyi]
21202120

2121-
[case testGenericClassAlternativeConstructorPrecise]
2121+
[case testGenericClassAlternativeConstructorPrecise2]
21222122
from typing import Generic, TypeVar, Type, Tuple, Any
21232123

21242124
T = TypeVar('T')

test-data/unit/check-inference.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -2614,7 +2614,7 @@ class C(B):
26142614
reveal_type(B.x) # N: Revealed type is "None"
26152615
reveal_type(C.x) # N: Revealed type is "None"
26162616

2617-
[case testLocalPartialTypesWithInheritance2]
2617+
[case testLocalPartialTypesWithInheritance3]
26182618
# flags: --local-partial-types
26192619
from typing import Optional
26202620

@@ -2652,7 +2652,7 @@ class C:
26522652
def f(self, x) -> None:
26532653
C.a.y # E: Item "None" of "Optional[Any]" has no attribute "y"
26542654

2655-
[case testLocalPartialTypesAccessPartialNoneAttribute]
2655+
[case testLocalPartialTypesAccessPartialNoneAttribute2]
26562656
# flags: --local-partial-types
26572657
class C:
26582658
a = None # E: Need type annotation for "a"

test-data/unit/check-modules.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- Type checker test cases dealing with modules and imports.
22
-- Towards the end there are tests for PEP 420 (namespace packages, i.e. __init__.py-less packages).
33

4-
[case testAccessImportedDefinitions]
4+
[case testAccessImportedDefinitions0]
55
import m
66
import typing
77
m.f() # E: Missing positional argument "a" in call to "f"
@@ -14,7 +14,7 @@ class A: pass
1414
def f(a: A) -> None: pass
1515
x = A()
1616

17-
[case testAccessImportedDefinitions]
17+
[case testAccessImportedDefinitions1]
1818
import m
1919
import typing
2020
m.f(object()) # E: Argument 1 to "f" has incompatible type "object"; expected "A"

test-data/unit/check-multiple-inheritance.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ class A(Base1, Base2):
502502
[out]
503503
main:10: error: Incompatible types in assignment (expression has type "GenericBase[Base2]", base class "Base1" defined the type as "GenericBase[Base1]")
504504

505-
[case testMultipleInheritance_NestedVariableOverriddenWithCompatibleType]
505+
[case testMultipleInheritance_NestedVariableOverriddenWithCompatibleType2]
506506
from typing import TypeVar, Generic
507507
T = TypeVar('T', covariant=True)
508508
class GenericBase(Generic[T]):

test-data/unit/check-newsemanal.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ reveal_type(x) # N: Revealed type is "builtins.int"
23142314

23152315
C = int
23162316

2317-
[case testNewAnalyzerCastForward2]
2317+
[case testNewAnalyzerCastForward3]
23182318
from typing import cast, NamedTuple
23192319

23202320
x = cast('C', None)

test-data/unit/check-overloading.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -4314,7 +4314,7 @@ class Wrapper3:
43144314
def foo(x: Union[int, str]): pass # E: Self argument missing for a non-static method (or an invalid type for self)
43154315
[builtins fixtures/staticmethod.pyi]
43164316

4317-
[case testOverloadWithSwappedDecorators]
4317+
[case testOverloadWithSwappedDecorators2]
43184318
from typing import overload
43194319

43204320
class Wrapper1:

test-data/unit/check-typeddict.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ from mypy_extensions import TypedDict
12641264
Point = TypedDict('Point', {'x': 1, 'y': 1}) # E: Invalid type: try using Literal[1] instead?
12651265
[builtins fixtures/dict.pyi]
12661266

1267-
[case testCannotCreateTypedDictTypeWithInvalidName]
1267+
[case testCannotCreateTypedDictTypeWithInvalidName2]
12681268
from mypy_extensions import TypedDict
12691269
X = TypedDict('Y', {'x': int}) # E: First argument "Y" to TypedDict() does not match variable name "X"
12701270
[builtins fixtures/dict.pyi]

test-data/unit/check-unions.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def f(x: M[C]) -> None:
241241
y = x.get(None)
242242
reveal_type(y) # N: Revealed type is "__main__.C"
243243

244-
[case testUnionSimplificationSpecialCases]
244+
[case testUnionSimplificationSpecialCases2]
245245
from typing import Any, TypeVar, Union
246246

247247
class C(Any): pass

test-data/unit/check-varargs.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ f(a) # E: Argument 1 to "f" has incompatible type "List[int]"; expected "Listene
735735
g(b) # E: Argument 1 to "g" has incompatible type "Dict[str, int]"; expected "DictReader"
736736
[builtins fixtures/dict.pyi]
737737

738-
[case testInvariantTypeConfusingNames]
738+
[case testInvariantTypeConfusingNames2]
739739
from typing import Iterable, Generic, TypeVar, List
740740

741741
T = TypeVar('T')

test-data/unit/deps-expressions.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def g(a: A) -> int:
191191
<m.f1> -> m.g
192192
<m.f2> -> m.g
193193

194-
[case testIndexExpr]
194+
[case testIndexExpr2]
195195
class A:
196196
def __getitem__(self, x: int) -> int: pass
197197

test-data/unit/fine-grained-blockers.test

+3-3
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ main:1: error: Cannot find implementation or library stub for module named "a"
338338
main:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
339339
b.py:1: error: Cannot find implementation or library stub for module named "a"
340340

341-
[case testDeleteFileWithBlockingError-only_when_cache]
341+
[case testDeleteFileWithBlockingError2-only_when_cache]
342342
-- Different cache/no-cache tests because:
343343
-- Error message ordering differs
344344
import a
@@ -521,7 +521,7 @@ a.py:1: error: invalid syntax. Perhaps you forgot a comma?
521521
b.py:2: error: Incompatible return value type (got "str", expected "int")
522522
==
523523

524-
[case testDecodeErrorBlocker-posix]
524+
[case testDecodeErrorBlocker1-posix]
525525
import a
526526
a.f(1)
527527
[file a.py]
@@ -537,7 +537,7 @@ mypy: can't decode file 'tmp/a.py': 'ascii' codec can't decode byte 0xc3 in posi
537537
==
538538
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
539539

540-
[case testDecodeErrorBlocker-windows]
540+
[case testDecodeErrorBlocker2-windows]
541541
import a
542542
a.f(1)
543543
[file a.py]

test-data/unit/fine-grained-follow-imports.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ main.py:3: error: Missing positional argument "x" in call to "f"
428428
main.py:3: error: Missing positional argument "x" in call to "f"
429429
==
430430

431-
[case testFollowImportsNormalPackage-only_when_cache]
431+
[case testFollowImportsNormalPackage2-only_when_cache]
432432
# flags: --follow-imports=normal
433433
# cmd: mypy main.py
434434

@@ -681,7 +681,7 @@ import bar
681681
src/bar.py:1: error: "int" not callable
682682
src/foo.py:2: error: "str" not callable
683683

684-
[case testFollowImportsNormalSearchPathUpdate-only_when_cache]
684+
[case testFollowImportsNormalSearchPathUpdate2-only_when_cache]
685685
# flags: --follow-imports=normal
686686
# cmd: mypy main.py
687687
# cmd2: mypy main.py src/foo.py

test-data/unit/fine-grained-modules.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ main:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missin
410410

411411
-- TODO: Fix this bug. It is a real bug that was been papered over
412412
-- by the test harness.
413-
[case testDeletionOfSubmoduleTriggersImportFrom1-only_when_cache-skip]
413+
[case testDeletionOfSubmoduleTriggersImportFrom1_2-only_when_cache-skip]
414414
-- Different cache/no-cache tests because:
415415
-- missing module error message mismatch
416416
from p import q
@@ -1752,7 +1752,7 @@ class Foo:
17521752
==
17531753
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"
17541754

1755-
[case testAddAndUseClass4]
1755+
[case testAddAndUseClass4_2]
17561756
[file a.py]
17571757
[file a.py.2]
17581758
from p.b import *

test-data/unit/fine-grained.test

+3-3
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ n.py:2: error: "A" has no attribute "g"
361361
==
362362
n.py:2: error: "A" has no attribute "g"
363363

364-
[case testContinueToReportErrorAtTopLevel-only_when_cache]
364+
[case testContinueToReportErrorAtTopLevel2-only_when_cache]
365365
-- Different cache/no-cache tests because:
366366
-- Error message ordering differs
367367
import n
@@ -7171,7 +7171,7 @@ main:4: note: def f(self, arg: int) -> int
71717171
main:4: note: @overload
71727172
main:4: note: def f(self, arg: str) -> str
71737173

7174-
[case testOverloadedMethodSupertype-only_when_nocache]
7174+
[case testOverloadedMethodSupertype2-only_when_nocache]
71757175
-- Different cache/no-cache tests because
71767176
-- CallableType.def_extras.first_arg differs ("self"/None)
71777177
from typing import overload, Any
@@ -8411,7 +8411,7 @@ a.py:3: note: def meth(self, x: str) -> str
84118411
a.py:3: note: Subclass:
84128412
a.py:3: note: def meth(self) -> None
84138413

8414-
[case testFinalBodyReprocessedAndStillFinalOverloaded-only_when_nocache]
8414+
[case testFinalBodyReprocessedAndStillFinalOverloaded2-only_when_nocache]
84158415
-- Different cache/no-cache tests because
84168416
-- CallableType.def_extras.first_arg differs ("self"/None)
84178417
import a

test-data/unit/parse-errors.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ file:1: error: invalid syntax
295295
[out]
296296
file:1: error: invalid syntax
297297

298-
[case testInvalidConditionInConditionalExpression2]
298+
[case testInvalidConditionInConditionalExpression3]
299299
1 if x else for y in z
300300
[out]
301301
file:1: error: invalid syntax

test-data/unit/parse.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -3123,7 +3123,7 @@ MypyFile:1(
31233123
NameExpr(x)
31243124
NameExpr(y)))))
31253125

3126-
[case testConditionalExpressionInListComprehension]
3126+
[case testConditionalExpressionInListComprehension2]
31273127
a = [ 1 if x else 2 for x in y ]
31283128
[out]
31293129
MypyFile:1(
@@ -3329,7 +3329,7 @@ MypyFile:1()
33293329
[out]
33303330
MypyFile:1()
33313331

3332-
[case testLatinUnixEncoding]
3332+
[case testLatinUnixEncoding2]
33333333
# coding: iso-latin-1
33343334
[out]
33353335
MypyFile:1()

test-data/unit/semanal-basic.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ MypyFile:1(
286286
NameExpr(x* [l])
287287
NameExpr(None [builtins.None])))))
288288

289-
[case testGlobalDeclScope]
289+
[case testGlobalDeclScope2]
290290
x = None
291291
def f():
292292
global x

test-data/unit/semanal-modules.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ MypyFile:1(
206206
NameExpr(_n)
207207
x [_n.x])))
208208

209-
[case testAccessingImportedModule]
209+
[case testAccessingImportedModule2]
210210
import _m
211211
_m._n.x
212212
[file _m.py]
@@ -385,7 +385,7 @@ MypyFile:1(
385385
NameExpr(None [builtins.None])
386386
m._n.c))
387387

388-
[case testSubmodulesAndTypes]
388+
[case testSubmodulesAndTypes2]
389389
from m._n import c
390390
x = None # type: c
391391
[file m/__init__.py]

test-data/unit/semanal-namedtuple.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ N = NamedTuple(name='N', fields=[]) # E: Unexpected arguments to "NamedTuple()"
207207

208208
-- NOTE: The following code works at runtime but is not yet supported by mypy.
209209
-- Keyword arguments may potentially be supported in the future.
210-
[case testNamedTupleWithNonpositionalArgs]
210+
[case testNamedTupleWithNonpositionalArgs2]
211211
from collections import namedtuple
212212
N = namedtuple(typename='N', field_names=['x']) # E: Unexpected arguments to "namedtuple()"
213213
[builtins fixtures/tuple.pyi]

test-data/unit/stubgen.test

+3-3
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ import re as re
483483

484484
x: int
485485

486-
[case testExportModule_import]
486+
[case testExportModule2_import]
487487
import re
488488
__all__ = ['re', 'x']
489489
x = 1
@@ -701,7 +701,7 @@ import x
701701

702702
class D(x.C): ...
703703

704-
[case testArbitraryBaseClass]
704+
[case testArbitraryBaseClass2]
705705
import x.y
706706
class D(x.y.C): ...
707707
[out]
@@ -837,7 +837,7 @@ import collections
837837
x: collections.defaultdict
838838

839839

840-
[case testAnnotationImports]
840+
[case testAnnotationImports2]
841841
from typing import List
842842
import collections
843843
x: List[collections.defaultdict]

test-data/unit/typexport-basic.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ f = lambda: [1]
727727
LambdaExpr(3) : def () -> builtins.list[builtins.int]
728728
NameExpr(3) : def () -> builtins.list[builtins.int]
729729

730-
[case testLambdaWithInferredType2]
730+
[case testLambdaWithInferredType3]
731731
from typing import List, Callable
732732
f = lambda x: [] # type: Callable[[B], List[A]]
733733
class A: pass

0 commit comments

Comments
 (0)