|
28 | 28 | from mypy.maptype import map_instance_to_supertype
|
29 | 29 | from mypy.meet import is_overlapping_types, narrow_declared_type
|
30 | 30 | from mypy.message_registry import ErrorMessage
|
31 |
| -from mypy.messages import MessageBuilder |
| 31 | +from mypy.messages import MessageBuilder, format_type |
32 | 32 | from mypy.nodes import (
|
33 | 33 | ARG_NAMED,
|
34 | 34 | ARG_POS,
|
|
116 | 116 | from mypy.type_visitor import TypeTranslator
|
117 | 117 | from mypy.typeanal import (
|
118 | 118 | check_for_explicit_any,
|
| 119 | + fix_instance, |
119 | 120 | has_any_from_unimported_type,
|
120 | 121 | instantiate_type_alias,
|
121 | 122 | make_optional_type,
|
122 | 123 | set_any_tvars,
|
| 124 | + validate_instance, |
123 | 125 | )
|
124 | 126 | from mypy.typeops import (
|
125 | 127 | callable_type,
|
|
166 | 168 | TypeVarLikeType,
|
167 | 169 | TypeVarTupleType,
|
168 | 170 | TypeVarType,
|
| 171 | + UnboundType, |
169 | 172 | UninhabitedType,
|
170 | 173 | UnionType,
|
171 | 174 | UnpackType,
|
172 | 175 | find_unpack_in_list,
|
| 176 | + flatten_nested_tuples, |
173 | 177 | flatten_nested_unions,
|
174 | 178 | get_proper_type,
|
175 | 179 | get_proper_types,
|
@@ -4637,15 +4641,35 @@ class C(Generic[T, Unpack[Ts]]): ...
|
4637 | 4641 | similar to how it is done in other places using split_with_prefix_and_suffix().
|
4638 | 4642 | """
|
4639 | 4643 | vars = t.variables
|
| 4644 | + args = flatten_nested_tuples(args) |
| 4645 | + |
| 4646 | + # TODO: this logic is duplicated with semanal_typeargs. |
| 4647 | + for tv, arg in zip(t.variables, args): |
| 4648 | + if isinstance(tv, ParamSpecType): |
| 4649 | + if not isinstance( |
| 4650 | + get_proper_type(arg), (Parameters, ParamSpecType, AnyType, UnboundType) |
| 4651 | + ): |
| 4652 | + self.chk.fail( |
| 4653 | + "Can only replace ParamSpec with a parameter types list or" |
| 4654 | + f" another ParamSpec, got {format_type(arg, self.chk.options)}", |
| 4655 | + ctx, |
| 4656 | + ) |
| 4657 | + return [AnyType(TypeOfAny.from_error)] * len(vars) |
| 4658 | + |
4640 | 4659 | if not vars or not any(isinstance(v, TypeVarTupleType) for v in vars):
|
4641 | 4660 | return list(args)
|
| 4661 | + assert t.is_type_obj() |
| 4662 | + info = t.type_object() |
| 4663 | + # We reuse the logic from semanal phase to reduce code duplication. |
| 4664 | + fake = Instance(info, args, line=ctx.line, column=ctx.column) |
| 4665 | + if not validate_instance(fake, self.chk.fail): |
| 4666 | + fix_instance( |
| 4667 | + fake, self.chk.fail, self.chk.note, disallow_any=False, options=self.chk.options |
| 4668 | + ) |
| 4669 | + args = list(fake.args) |
4642 | 4670 |
|
4643 | 4671 | prefix = next(i for (i, v) in enumerate(vars) if isinstance(v, TypeVarTupleType))
|
4644 | 4672 | suffix = len(vars) - prefix - 1
|
4645 |
| - if len(args) < len(vars) - 1: |
4646 |
| - self.msg.incompatible_type_application(len(vars), len(args), ctx) |
4647 |
| - return [AnyType(TypeOfAny.from_error)] * len(vars) |
4648 |
| - |
4649 | 4673 | tvt = vars[prefix]
|
4650 | 4674 | assert isinstance(tvt, TypeVarTupleType)
|
4651 | 4675 | start, middle, end = split_with_prefix_and_suffix(tuple(args), prefix, suffix)
|
|
0 commit comments