diff --git a/mypy/fastparse.py b/mypy/fastparse.py index e85b8fffaf9e..1d8e5811827b 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -1957,7 +1957,9 @@ def visit_Call(self, e: Call) -> Type: if not isinstance(self.parent(), ast3.List): note = None - if constructor: + if constructor and not e.keywords: + # Only suggest Foo[...] when there are no keyword arguments, + # since Foo[arg=val] is a SyntaxError (see #16506). note = "Suggestion: use {0}[...] instead of {0}(...)".format(constructor) return self.invalid_type(e, note=note) if not constructor: diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 85a2264c2088..80ad703bfe32 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -122,6 +122,11 @@ for v in x: # type: int, int # E: Syntax error in type annotation [syntax] \ # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) pass +[case testErrorCodeSyntaxError4_no_native_parse] +# Keyword arguments in type annotation should not suggest Foo[...] (see #16506) +def f(a: Foo(arg=int)) -> int: # E: Invalid type comment or annotation [valid-type] + pass + [case testErrorCodeSyntaxErrorIgnoreNote] # This is a bit inconsistent -- syntax error would be more logical? x: 'a b' # type: ignore[valid-type] diff --git a/test-data/unit/check-fastparse.test b/test-data/unit/check-fastparse.test index 7ee5a9c43216..6596dd36adef 100644 --- a/test-data/unit/check-fastparse.test +++ b/test-data/unit/check-fastparse.test @@ -207,6 +207,18 @@ def f(a: Foo(int)) -> int: main:7: error: Invalid type comment or annotation main:7: note: Suggestion: use Foo[...] instead of Foo(...) +[case testFasterParseTypeErrorCustomWithKeyword_no_native_parse] + +from typing import TypeVar, Generic +T = TypeVar('T') +class Foo(Generic[T]): + pass + +def f(a: Foo(arg=int)) -> int: + pass +[out] +main:7: error: Invalid type comment or annotation + [case testFastParseMatMul] from typing import Any