Skip to content

Commit 128661c

Browse files
hauntsaninjaJukkaL
authored andcommitted
Friendlier errors for PEP 612 (#12832)
Co-authored-by: hauntsaninja <>
1 parent a54c84d commit 128661c

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

mypy/typeanal.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -944,9 +944,13 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
944944
)
945945
if maybe_ret is None:
946946
# Callable[?, RET] (where ? is something invalid)
947-
# TODO(PEP612): change error to mention paramspec, once we actually have some
948-
# support for it
949-
self.fail('The first argument to Callable must be a list of types or "..."', t)
947+
self.fail(
948+
'The first argument to Callable must be a '
949+
'list of types, parameter specification, or "..."', t)
950+
self.note(
951+
'See https://mypy.readthedocs.io/en/stable/kinds_of_types.html#callable-types-and-lambdas', # noqa: E501
952+
t
953+
)
950954
return AnyType(TypeOfAny.from_error)
951955
ret = maybe_ret
952956
else:
@@ -1180,6 +1184,10 @@ def anal_type(self, t: Type, nested: bool = True, *, allow_param_spec: bool = Fa
11801184
and analyzed.flavor == ParamSpecFlavor.BARE):
11811185
if analyzed.prefix.arg_types:
11821186
self.fail('Invalid location for Concatenate', t)
1187+
self.note(
1188+
'You can use Concatenate as the first argument to Callable',
1189+
t
1190+
)
11831191
else:
11841192
self.fail(f'Invalid location for ParamSpec "{analyzed.name}"', t)
11851193
self.note(

test-data/unit/check-parameter-specification.test

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ def foo1(x: Callable[P, int]) -> Callable[P, str]: ...
2525
def foo2(x: P) -> P: ... # E: Invalid location for ParamSpec "P" \
2626
# N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]'
2727

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

3031
def foo4(x: List[P]) -> None: ... # E: Invalid location for ParamSpec "P" \
3132
# N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]'

test-data/unit/semanal-errors.test

+2-1
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,8 @@ x = None # type: Callable[int, str]
867867
y = None # type: Callable[int]
868868
z = None # type: Callable[int, int, int]
869869
[out]
870-
main:2: error: The first argument to Callable must be a list of types or "..."
870+
main:2: error: The first argument to Callable must be a list of types, parameter specification, or "..."
871+
main:2: note: See https://mypy.readthedocs.io/en/stable/kinds_of_types.html#callable-types-and-lambdas
871872
main:3: error: Please use "Callable[[<parameters>], <return type>]" or "Callable"
872873
main:4: error: Please use "Callable[[<parameters>], <return type>]" or "Callable"
873874

0 commit comments

Comments
 (0)