@@ -304,14 +304,14 @@ def not_declared_in_type_params(self, tvar_name: str) -> bool:
304304
305305 def visit_unbound_type_nonoptional (self , t : UnboundType , defining_literal : bool ) -> Type :
306306 sym = self .lookup_qualified (t .name , t )
307- paramspec_name = None
307+ param_spec_name = None
308308 if t .name .endswith ((".args" , ".kwargs" )):
309- paramspec_name = t .name .rsplit ("." , 1 )[0 ]
310- maybe_pspec = self .lookup_qualified (paramspec_name , t )
311- if maybe_pspec and isinstance (maybe_pspec .node , ParamSpecExpr ):
312- sym = maybe_pspec
309+ param_spec_name = t .name .rsplit ("." , 1 )[0 ]
310+ maybe_param_spec = self .lookup_qualified (param_spec_name , t )
311+ if maybe_param_spec and isinstance (maybe_param_spec .node , ParamSpecExpr ):
312+ sym = maybe_param_spec
313313 else :
314- paramspec_name = None
314+ param_spec_name = None
315315
316316 if sym is not None :
317317 node = sym .node
@@ -365,7 +365,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
365365 if tvar_def is None :
366366 if self .allow_unbound_tvars :
367367 return t
368- name = paramspec_name or t .name
368+ name = param_spec_name or t .name
369369 if self .defining_alias and self .not_declared_in_type_params (t .name ):
370370 msg = f'ParamSpec "{ name } " is not included in type_params'
371371 else :
@@ -377,7 +377,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
377377 self .fail (
378378 f'ParamSpec "{ t .name } " used with arguments' , t , code = codes .VALID_TYPE
379379 )
380- if paramspec_name is not None and not self .allow_param_spec_literals :
380+ if param_spec_name is not None and not self .allow_param_spec_literals :
381381 self .fail (
382382 "ParamSpec components are not allowed here" , t , code = codes .VALID_TYPE
383383 )
@@ -1110,20 +1110,25 @@ def visit_callable_type(
11101110
11111111 arg_kinds = t .arg_kinds
11121112 arg_types = []
1113- pspec_with_args = pspec_with_kwargs = None
1114- for i , ut in enumerate ( t . arg_types ):
1115- kind = arg_kinds [ i ]
1113+ param_spec_with_args = param_spec_with_kwargs = None
1114+ param_spec_invalid = False
1115+ for kind , ut in zip ( arg_kinds , t . arg_types ):
11161116 if kind == ARG_STAR :
1117- pspec_with_args , at = self .anal_star_arg_type (ut , kind , nested = nested )
1117+ param_spec_with_args , at = self .anal_star_arg_type (ut , kind , nested = nested )
11181118 elif kind == ARG_STAR2 :
1119- pspec_with_kwargs , at = self .anal_star_arg_type (ut , kind , nested = nested )
1119+ param_spec_with_kwargs , at = self .anal_star_arg_type (ut , kind , nested = nested )
11201120 else :
1121- if pspec_with_args :
1122- self .fail ("Arguments not allowed after ParamSpec.args" , t )
1121+ if param_spec_with_args :
1122+ param_spec_invalid = True
1123+ self .fail (
1124+ "Arguments not allowed after ParamSpec.args" , t , code = codes .VALID_TYPE
1125+ )
11231126 at = self .anal_type (ut , nested = nested , allow_unpack = False )
11241127 arg_types .append (at )
11251128
11261129 if nested and arg_types :
1130+ # If we've got a Callable[[Unpack[SomeTypedDict]], None], make sure
1131+ # Unpack is interpreted as `**` and not as `*`.
11271132 last = arg_types [- 1 ]
11281133 if isinstance (last , UnpackType ):
11291134 # TODO: it would be better to avoid this get_proper_type() call.
@@ -1136,12 +1141,18 @@ def visit_callable_type(
11361141 unpacked_kwargs = True
11371142 arg_types = self .check_unpacks_in_list (arg_types )
11381143
1139- if pspec_with_args != pspec_with_kwargs :
1140- name = pspec_with_args or pspec_with_kwargs
1144+ if not param_spec_invalid and param_spec_with_args != param_spec_with_kwargs :
1145+ # If already invalid, do not report more errors - definition has
1146+ # to be fixed anyway
1147+ name = param_spec_with_args or param_spec_with_kwargs
11411148 self .fail (
11421149 f'ParamSpec must have "*args" typed as "{ name } .args" and "**kwargs" typed as "{ name } .kwargs"' ,
11431150 t ,
1151+ code = codes .VALID_TYPE ,
11441152 )
1153+ param_spec_invalid = True
1154+
1155+ if param_spec_invalid :
11451156 if ARG_STAR in arg_kinds :
11461157 arg_types [arg_kinds .index (ARG_STAR )] = AnyType (TypeOfAny .from_error )
11471158 if ARG_STAR2 in arg_kinds :
0 commit comments