Skip to content

Commit

Permalink
Improve error message for invalid tuple types like (int, str). #4173 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
MentalMegalodon authored and msullivan committed May 14, 2018
1 parent a6dbbbb commit ee2195a
Show file tree
Hide file tree
Showing 7 changed files with 16 additions and 12 deletions.
4 changes: 3 additions & 1 deletion mypy/typeanal.py
Expand Up @@ -419,9 +419,11 @@ def visit_tuple_type(self, t: TupleType) -> Type:
# Types such as (t1, t2, ...) only allowed in assignment statements. They'll
# generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead.
if t.implicit and not self.allow_tuple_literal:
self.fail('Invalid tuple literal type', t)
self.fail('Syntax error in type annotation', t)
if len(t.items) == 1:
self.note_func('Suggestion: Is there a spurious trailing comma?', t)
else:
self.note_func('Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)', t)
return AnyType(TypeOfAny.from_error)
star_count = sum(1 for item in t.items if isinstance(item, StarType))
if star_count > 1:
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-async-await.test
Expand Up @@ -335,7 +335,7 @@ async def f() -> None:
async with C() as y, C() as z: # type: str, int # E: Incompatible types in assignment (expression has type "int", variable has type "str")
pass

async with C() as a: # type: int, int # E: Invalid tuple literal type
async with C() as a: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
pass
[builtins fixtures/async_await.pyi]
[typing fixtures/typing-full.pyi]
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-fastparse.test
Expand Up @@ -433,5 +433,5 @@ def update_state(tid, # type: int
): # type: (...) -> str
pass
[out]
main:3: error: Invalid tuple literal type
main:3: error: Syntax error in type annotation
main:3: note: Suggestion: Is there a spurious trailing comma?
2 changes: 1 addition & 1 deletion test-data/unit/check-functions.test
Expand Up @@ -2212,7 +2212,7 @@ foo(y=2) # E: Missing positional arguments
def dec(f): pass

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

[case testReturnTypeLineNumberNewLine]
Expand Down
9 changes: 4 additions & 5 deletions test-data/unit/check-statements.test
Expand Up @@ -182,7 +182,7 @@ for z in x: # type: int
for w in x: # type: Union[int, str]
reveal_type(w) # E: Revealed type is 'Union[builtins.int, builtins.str]'

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

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

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

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

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

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

with A() as i, A() as (j, k), B() as l: # type: (int, int), (int, int), str # E: Invalid tuple literal type
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)
pass

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
Expand Down Expand Up @@ -1615,4 +1615,3 @@ N = TypedDict('N', {'x': int})
[builtins fixtures/dict.pyi]
[typing fixtures/typing-full.pyi]
[out]

6 changes: 4 additions & 2 deletions test-data/unit/fine-grained.test
Expand Up @@ -3872,9 +3872,11 @@ def inner():
# type: () -> (str, int)
return 'lol', 10
[out]
a.py:1: error: Invalid tuple literal type
a.py:1: error: Syntax error in type annotation
a.py:1: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
==
a.py:2: error: Invalid tuple literal type
a.py:2: error: Syntax error in type annotation
a.py:2: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)

[case testImplicitTuple3]
import a
Expand Down
3 changes: 2 additions & 1 deletion test-data/unit/semanal-types.test
Expand Up @@ -1474,7 +1474,8 @@ MypyFile:1(
[case testTupleExpressionAsType]
def f(x: (int, int)) -> None: pass
[out]
main:1: error: Invalid tuple literal type
main:1: error: Syntax error in type annotation
main:1: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)

[case tesQualifiedTypeNameBasedOnAny]
from typing import Any
Expand Down

0 comments on commit ee2195a

Please sign in to comment.