Skip to content

Commit

Permalink
Friendlier errors for PEP 612 (#12832)
Browse files Browse the repository at this point in the history
Co-authored-by: hauntsaninja <>
  • Loading branch information
hauntsaninja authored and JukkaL committed May 23, 2022
1 parent a54c84d commit 128661c
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 5 deletions.
14 changes: 11 additions & 3 deletions mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,9 +944,13 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
)
if maybe_ret is None:
# Callable[?, RET] (where ? is something invalid)
# TODO(PEP612): change error to mention paramspec, once we actually have some
# support for it
self.fail('The first argument to Callable must be a list of types or "..."', t)
self.fail(
'The first argument to Callable must be a '
'list of types, parameter specification, or "..."', t)
self.note(
'See https://mypy.readthedocs.io/en/stable/kinds_of_types.html#callable-types-and-lambdas', # noqa: E501
t
)
return AnyType(TypeOfAny.from_error)
ret = maybe_ret
else:
Expand Down Expand Up @@ -1180,6 +1184,10 @@ def anal_type(self, t: Type, nested: bool = True, *, allow_param_spec: bool = Fa
and analyzed.flavor == ParamSpecFlavor.BARE):
if analyzed.prefix.arg_types:
self.fail('Invalid location for Concatenate', t)
self.note(
'You can use Concatenate as the first argument to Callable',
t
)
else:
self.fail(f'Invalid location for ParamSpec "{analyzed.name}"', t)
self.note(
Expand Down
3 changes: 2 additions & 1 deletion test-data/unit/check-parameter-specification.test
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def foo1(x: Callable[P, int]) -> Callable[P, str]: ...
def foo2(x: P) -> P: ... # E: Invalid location for ParamSpec "P" \
# N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]'

def foo3(x: Concatenate[int, P]) -> int: ... # E: Invalid location for Concatenate
def foo3(x: Concatenate[int, P]) -> int: ... # E: Invalid location for Concatenate \
# N: You can use Concatenate as the first argument to Callable

def foo4(x: List[P]) -> None: ... # E: Invalid location for ParamSpec "P" \
# N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]'
Expand Down
3 changes: 2 additions & 1 deletion test-data/unit/semanal-errors.test
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,8 @@ x = None # type: Callable[int, str]
y = None # type: Callable[int]
z = None # type: Callable[int, int, int]
[out]
main:2: error: The first argument to Callable must be a list of types or "..."
main:2: error: The first argument to Callable must be a list of types, parameter specification, or "..."
main:2: note: See https://mypy.readthedocs.io/en/stable/kinds_of_types.html#callable-types-and-lambdas
main:3: error: Please use "Callable[[<parameters>], <return type>]" or "Callable"
main:4: error: Please use "Callable[[<parameters>], <return type>]" or "Callable"

Expand Down

0 comments on commit 128661c

Please sign in to comment.