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

Function partial_call_callback

mypy/plugins/functools.py:337–399  ·  view source on GitHub ↗

Infer a more precise return type for functools.partial.__call__.

(ctx: mypy.plugin.MethodContext)

Source from the content-addressed store, hash-verified

335
336
337def partial_call_callback(ctx: mypy.plugin.MethodContext) -> Type:
338 """Infer a more precise return type for functools.partial.__call__."""
339 if (
340 not isinstance(ctx.api, mypy.checker.TypeChecker) # use internals
341 or not isinstance(ctx.type, Instance)
342 or ctx.type.type.fullname != PARTIAL
343 or not ctx.type.extra_attrs
344 or "__mypy_partial" not in ctx.type.extra_attrs.attrs
345 ):
346 return ctx.default_return_type
347
348 extra_attrs = ctx.type.extra_attrs
349 partial_type = get_proper_type(extra_attrs.attrs["__mypy_partial"])
350 if len(ctx.arg_types) != 2: # *args, **kwargs
351 return ctx.default_return_type
352
353 # See comments for similar actual to formal code above
354 actual_args = []
355 actual_arg_kinds = []
356 actual_arg_names = []
357 seen_args = set()
358 for i, param in enumerate(ctx.args):
359 for j, a in enumerate(param):
360 if a in seen_args:
361 continue
362 seen_args.add(a)
363 actual_args.append(a)
364 actual_arg_kinds.append(ctx.arg_kinds[i][j])
365 actual_arg_names.append(ctx.arg_names[i][j])
366
367 result, _ = ctx.api.expr_checker.check_call(
368 callee=partial_type,
369 args=actual_args,
370 arg_kinds=actual_arg_kinds,
371 arg_names=actual_arg_names,
372 context=ctx.context,
373 )
374 if not isinstance(partial_type, CallableType) or partial_type.param_spec() is None:
375 return result
376
377 args_bound = "__mypy_partial_paramspec_args_bound" in extra_attrs.immutable
378 kwargs_bound = "__mypy_partial_paramspec_kwargs_bound" in extra_attrs.immutable
379
380 passed_paramspec_parts = [
381 arg.node.type
382 for arg in actual_args
383 if isinstance(arg, NameExpr)
384 and isinstance(arg.node, Var)
385 and isinstance(arg.node.type, ParamSpecType)
386 ]
387 # ensure *args: P.args
388 args_passed = any(part.flavor == ParamSpecFlavor.ARGS for part in passed_paramspec_parts)
389 if not args_bound and not args_passed:
390 ctx.api.expr_checker.msg.too_few_arguments(partial_type, ctx.context, actual_arg_names)
391 elif args_bound and args_passed:
392 ctx.api.expr_checker.msg.too_many_arguments(partial_type, ctx.context)
393
394 # ensure **kwargs: P.kwargs

Callers

nothing calls this directly

Calls 12

get_proper_typeFunction · 0.90
isinstanceFunction · 0.85
lenFunction · 0.85
setClass · 0.85
enumerateFunction · 0.85
anyFunction · 0.85
appendMethod · 0.80
param_specMethod · 0.80
too_few_argumentsMethod · 0.80
too_many_argumentsMethod · 0.80
addMethod · 0.45
check_callMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…