Skip to content

Commit ee2195a

Browse files
MentalMegalodonmsullivan
authored andcommitted
Improve error message for invalid tuple types like (int, str). #4173 (#5042)
1 parent a6dbbbb commit ee2195a

7 files changed

+16
-12
lines changed

mypy/typeanal.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,11 @@ def visit_tuple_type(self, t: TupleType) -> Type:
419419
# Types such as (t1, t2, ...) only allowed in assignment statements. They'll
420420
# generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead.
421421
if t.implicit and not self.allow_tuple_literal:
422-
self.fail('Invalid tuple literal type', t)
422+
self.fail('Syntax error in type annotation', t)
423423
if len(t.items) == 1:
424424
self.note_func('Suggestion: Is there a spurious trailing comma?', t)
425+
else:
426+
self.note_func('Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)', t)
425427
return AnyType(TypeOfAny.from_error)
426428
star_count = sum(1 for item in t.items if isinstance(item, StarType))
427429
if star_count > 1:

test-data/unit/check-async-await.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ async def f() -> None:
335335
async with C() as y, C() as z: # type: str, int # E: Incompatible types in assignment (expression has type "int", variable has type "str")
336336
pass
337337

338-
async with C() as a: # type: int, int # E: Invalid tuple literal type
338+
async with C() as a: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
339339
pass
340340
[builtins fixtures/async_await.pyi]
341341
[typing fixtures/typing-full.pyi]

test-data/unit/check-fastparse.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,5 +433,5 @@ def update_state(tid, # type: int
433433
): # type: (...) -> str
434434
pass
435435
[out]
436-
main:3: error: Invalid tuple literal type
436+
main:3: error: Syntax error in type annotation
437437
main:3: note: Suggestion: Is there a spurious trailing comma?

test-data/unit/check-functions.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2212,7 +2212,7 @@ foo(y=2) # E: Missing positional arguments
22122212
def dec(f): pass
22132213

22142214
@dec
2215-
def test(a: str) -> (str,): # E: Invalid tuple literal type # N: Suggestion: Is there a spurious trailing comma?
2215+
def test(a: str) -> (str,): # E: Syntax error in type annotation # N: Suggestion: Is there a spurious trailing comma?
22162216
return None
22172217

22182218
[case testReturnTypeLineNumberNewLine]

test-data/unit/check-statements.test

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ for z in x: # type: int
182182
for w in x: # type: Union[int, str]
183183
reveal_type(w) # E: Revealed type is 'Union[builtins.int, builtins.str]'
184184

185-
for v in x: # type: int, int # E: Invalid tuple literal type
185+
for v in x: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
186186
pass
187187
[builtins fixtures/list.pyi]
188188

@@ -191,7 +191,7 @@ for v in x: # type: int, int # E: Invalid tuple literal type
191191
from typing import List, Tuple
192192
x = [] # type: List[Tuple[int, int]]
193193

194-
for y in x: # type: int, int # E: Invalid tuple literal type
194+
for y in x: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
195195
pass
196196

197197
for z in x: # type: Tuple[int, int]
@@ -1331,7 +1331,7 @@ with A() as a: # type: int
13311331
with A() as b: # type: str # E: Incompatible types in assignment (expression has type "int", variable has type "str")
13321332
pass
13331333

1334-
with A() as c: # type: int, int # E: Invalid tuple literal type
1334+
with A() as c: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
13351335
pass
13361336

13371337
with A() as d: # type: Union[int, str]
@@ -1386,7 +1386,7 @@ with A() as a, A() as (b, c), B() as d: # type: Tuple[int, int], (int, int), st
13861386
with A() as e, A() as (f, g), B() as h: # type: Tuple[int, int], Tuple[int, int], str
13871387
pass
13881388

1389-
with A() as i, A() as (j, k), B() as l: # type: (int, int), (int, int), str # E: Invalid tuple literal type
1389+
with A() as i, A() as (j, k), B() as l: # type: (int, int), (int, int), str # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
13901390
pass
13911391

13921392
with A(), A(), B() as m, A() as n, B(), B() as o: # type: int, Tuple[int, int] # E: Incompatible number of types for `with` targets
@@ -1615,4 +1615,3 @@ N = TypedDict('N', {'x': int})
16151615
[builtins fixtures/dict.pyi]
16161616
[typing fixtures/typing-full.pyi]
16171617
[out]
1618-

test-data/unit/fine-grained.test

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3872,9 +3872,11 @@ def inner():
38723872
# type: () -> (str, int)
38733873
return 'lol', 10
38743874
[out]
3875-
a.py:1: error: Invalid tuple literal type
3875+
a.py:1: error: Syntax error in type annotation
3876+
a.py:1: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
38763877
==
3877-
a.py:2: error: Invalid tuple literal type
3878+
a.py:2: error: Syntax error in type annotation
3879+
a.py:2: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
38783880

38793881
[case testImplicitTuple3]
38803882
import a

test-data/unit/semanal-types.test

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,8 @@ MypyFile:1(
14741474
[case testTupleExpressionAsType]
14751475
def f(x: (int, int)) -> None: pass
14761476
[out]
1477-
main:1: error: Invalid tuple literal type
1477+
main:1: error: Syntax error in type annotation
1478+
main:1: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
14781479

14791480
[case tesQualifiedTypeNameBasedOnAny]
14801481
from typing import Any

0 commit comments

Comments
 (0)