MCPcopy Index your code
hub / github.com/python/mypy / split_for_callable

Method split_for_callable

mypy/checkexpr.py:5031–5088  ·  view source on GitHub ↗

Handle directly applying type arguments to a variadic Callable. This is needed in situations where e.g. variadic class object appears in runtime context. For example: class C(Generic[T, Unpack[Ts]]): ... x = C[int, str]() We simply group the argument

(
        self, t: CallableType, args: Sequence[Type], ctx: Context
    )

Source from the content-addressed store, hash-verified

5029 return self.named_type("typing._SpecialForm")
5030
5031 def split_for_callable(
5032 self, t: CallableType, args: Sequence[Type], ctx: Context
5033 ) -> list[Type]:
5034 """Handle directly applying type arguments to a variadic Callable.
5035
5036 This is needed in situations where e.g. variadic class object appears in
5037 runtime context. For example:
5038 class C(Generic[T, Unpack[Ts]]): ...
5039 x = C[int, str]()
5040
5041 We simply group the arguments that need to go into Ts variable into a TupleType,
5042 similar to how it is done in other places using split_with_prefix_and_suffix().
5043 """
5044 if t.is_type_obj():
5045 # Type arguments must map to class type variables, ignoring constructor vars.
5046 vars = t.type_object().defn.type_vars
5047 else:
5048 vars = list(t.variables)
5049 args = flatten_nested_tuples(args)
5050
5051 # TODO: this logic is duplicated with semanal_typeargs.
5052 for tv, arg in zip(t.variables, args):
5053 if isinstance(tv, ParamSpecType):
5054 if not isinstance(
5055 get_proper_type(arg), (Parameters, ParamSpecType, AnyType, UnboundType)
5056 ):
5057 self.chk.fail(
5058 "Can only replace ParamSpec with a parameter types list or"
5059 f" another ParamSpec, got {format_type(arg, self.chk.options)}",
5060 ctx,
5061 )
5062 return [AnyType(TypeOfAny.from_error)] * len(vars)
5063
5064 # TODO: in future we may want to support type application to variadic functions.
5065 if (
5066 not vars
5067 or not any(isinstance(v, TypeVarTupleType) for v in vars)
5068 or not t.is_type_obj()
5069 ):
5070 return list(args)
5071 info = t.type_object()
5072 # We reuse the logic from semanal phase to reduce code duplication.
5073 fake = Instance(info, args, line=ctx.line, column=ctx.column)
5074 # This code can be only called either from checking a type application, or from
5075 # checking a type alias (after the caller handles no_args aliases), so we know it
5076 # was initially an IndexExpr, and we allow empty tuple type arguments.
5077 if not validate_instance(fake, self.chk.fail, indexed=True):
5078 fix_instance(
5079 fake, self.chk.fail, self.chk.note, disallow_any=False, options=self.chk.options
5080 )
5081 args = list(fake.args)
5082
5083 prefix = next(i for (i, v) in enumerate(vars) if isinstance(v, TypeVarTupleType))
5084 suffix = len(vars) - prefix - 1
5085 tvt = vars[prefix]
5086 assert isinstance(tvt, TypeVarTupleType)
5087 start, middle, end = split_with_prefix_and_suffix(tuple(args), prefix, suffix)
5088 return list(start) + [TupleType(list(middle), tvt.tuple_fallback)] + list(end)

Callers 1

Calls 15

flatten_nested_tuplesFunction · 0.90
get_proper_typeFunction · 0.90
format_typeFunction · 0.90
AnyTypeClass · 0.90
InstanceClass · 0.90
validate_instanceFunction · 0.90
fix_instanceFunction · 0.90
TupleTypeClass · 0.90
listClass · 0.85
zipFunction · 0.85
isinstanceFunction · 0.85

Tested by

no test coverage detected