Skip to content

Commit f3c27b2

Browse files
Produce better error on invalid types like List(int)
Fixes #4172
1 parent f07423c commit f3c27b2

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

mypy/fastparse.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,10 @@ def fail(self, msg: str, line: int, column: int) -> None:
10151015
if self.errors:
10161016
self.errors.report(line, column, msg)
10171017

1018+
def note(self, msg: str, line: int, column: int) -> None:
1019+
if self.errors:
1020+
self.errors.report(line, column, msg, severity='note')
1021+
10181022
def visit_raw_str(self, s: str) -> Type:
10191023
# An escape hatch that allows the AST walker in fastparse2 to
10201024
# directly hook into the Python 3.5 type converter in some cases
@@ -1031,12 +1035,19 @@ def translate_expr_list(self, l: Sequence[ast3.expr]) -> List[Type]:
10311035

10321036
def visit_Call(self, e: ast3.Call) -> Type:
10331037
# Parse the arg constructor
1034-
if not isinstance(self.parent(), ast3.List):
1035-
return self.generic_visit(e)
10361038
f = e.func
10371039
constructor = stringify_name(f)
1040+
1041+
if not isinstance(self.parent(), ast3.List):
1042+
self.fail(TYPE_COMMENT_AST_ERROR, self.line, e.col_offset)
1043+
if constructor:
1044+
self.note("Suggestion: use {}[...] instead of {}(...)".format(
1045+
constructor, constructor),
1046+
self.line, e.col_offset)
1047+
return AnyType(TypeOfAny.from_error)
10381048
if not constructor:
10391049
self.fail("Expected arg constructor name", e.lineno, e.col_offset)
1050+
10401051
name = None # type: Optional[str]
10411052
default_type = AnyType(TypeOfAny.special_form)
10421053
typ = default_type # type: Type

test-data/unit/check-fastparse.test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,30 @@ def f(a):
235235
pass
236236
[out]
237237
main:3: error: invalid type comment or annotation
238+
main:3: note: Suggestion: use Tuple[...] instead of Tuple(...)
239+
240+
[case testFasterParseTypeErrorList_python2]
241+
242+
from typing import List
243+
def f(a):
244+
# type: (List(int)) -> int
245+
pass
246+
[out]
247+
main:3: error: invalid type comment or annotation
248+
main:3: note: Suggestion: use List[...] instead of List(...)
249+
250+
[case testFasterParseTypeErrorCustom]
251+
252+
from typing import TypeVar, Generic
253+
T = TypeVar('T')
254+
class Foo(Generic[T]):
255+
pass
256+
257+
def f(a: Foo(int)) -> int:
258+
pass
259+
[out]
260+
main:7: error: invalid type comment or annotation
261+
main:7: note: Suggestion: use Foo[...] instead of Foo(...)
238262

239263
[case testFastParseMatMul]
240264

0 commit comments

Comments
 (0)