Skip to content

Commit 643a0db

Browse files
committed
Fix runtime crash in prefect, clean up naming
1 parent dfa0887 commit 643a0db

File tree

2 files changed

+32
-21
lines changed

2 files changed

+32
-21
lines changed

mypy/typeanal.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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:

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,13 @@ class C(Generic[P, P2]):
454454
def m1(self, *args: P.args, **kwargs: P.kwargs) -> None:
455455
self.m1(*args, **kwargs)
456456
self.m2(*args, **kwargs) # E: Argument 1 to "m2" of "C" has incompatible type "*P.args"; expected "P2.args" \
457-
# E: Argument 2 to "m2" of "C" has incompatible type "**P.kwargs"; expected "P2.kwargs"
457+
# E: Argument 2 to "m2" of "C" has incompatible type "**P.kwargs"; expected "P2.kwargs"
458458
self.m1(*kwargs, **args) # E: Argument 1 to "m1" of "C" has incompatible type "*P.kwargs"; expected "P.args" \
459-
# E: Argument 2 to "m1" of "C" has incompatible type "**P.args"; expected "P.kwargs"
459+
# E: Argument 2 to "m1" of "C" has incompatible type "**P.args"; expected "P.kwargs"
460460
self.m3(*args, **kwargs) # E: Argument 1 to "m3" of "C" has incompatible type "*P.args"; expected "int" \
461-
# E: Argument 2 to "m3" of "C" has incompatible type "**P.kwargs"; expected "int"
461+
# E: Argument 2 to "m3" of "C" has incompatible type "**P.kwargs"; expected "int"
462462
self.m4(*args, **kwargs) # E: Argument 1 to "m4" of "C" has incompatible type "*P.args"; expected "int" \
463-
# E: Argument 2 to "m4" of "C" has incompatible type "**P.kwargs"; expected "int"
463+
# E: Argument 2 to "m4" of "C" has incompatible type "**P.kwargs"; expected "int"
464464

465465
self.m1(*args, **args) # E: Argument 2 to "m1" of "C" has incompatible type "**P.args"; expected "P.kwargs"
466466
self.m1(*kwargs, **kwargs) # E: Argument 1 to "m1" of "C" has incompatible type "*P.kwargs"; expected "P.args"

0 commit comments

Comments
 (0)