Returns all overload call targets that having matching argument counts. If the given args contains a star-arg (*arg or **kwarg argument, except for ParamSpec), this method will ensure all star-arg overloads appear at the start of the list, instead of their usual location.
(
self,
arg_types: list[Type],
arg_kinds: list[ArgKind],
arg_names: Sequence[str | None] | None,
overload: Overloaded,
)
| 2912 | return result |
| 2913 | |
| 2914 | def plausible_overload_call_targets( |
| 2915 | self, |
| 2916 | arg_types: list[Type], |
| 2917 | arg_kinds: list[ArgKind], |
| 2918 | arg_names: Sequence[str | None] | None, |
| 2919 | overload: Overloaded, |
| 2920 | ) -> list[CallableType]: |
| 2921 | """Returns all overload call targets that having matching argument counts. |
| 2922 | |
| 2923 | If the given args contains a star-arg (*arg or **kwarg argument, except for |
| 2924 | ParamSpec), this method will ensure all star-arg overloads appear at the start |
| 2925 | of the list, instead of their usual location. |
| 2926 | |
| 2927 | The only exception is if the starred argument is something like a Tuple or a |
| 2928 | NamedTuple, which has a definitive "shape". If so, we don't move the corresponding |
| 2929 | alternative to the front since we can infer a more precise match using the original |
| 2930 | order.""" |
| 2931 | |
| 2932 | def has_shape(typ: Type) -> bool: |
| 2933 | typ = get_proper_type(typ) |
| 2934 | return isinstance(typ, (TupleType, TypedDictType)) or ( |
| 2935 | isinstance(typ, Instance) and typ.type.is_named_tuple |
| 2936 | ) |
| 2937 | |
| 2938 | matches: list[CallableType] = [] |
| 2939 | star_matches: list[CallableType] = [] |
| 2940 | |
| 2941 | args_have_var_arg = False |
| 2942 | args_have_kw_arg = False |
| 2943 | for kind, typ in zip(arg_kinds, arg_types): |
| 2944 | if kind == ARG_STAR and not has_shape(typ): |
| 2945 | args_have_var_arg = True |
| 2946 | if kind == ARG_STAR2 and not has_shape(typ): |
| 2947 | args_have_kw_arg = True |
| 2948 | |
| 2949 | for typ in overload.items: |
| 2950 | formal_to_actual = map_actuals_to_formals( |
| 2951 | arg_kinds, arg_names, typ.arg_kinds, typ.arg_names, lambda i: arg_types[i] |
| 2952 | ) |
| 2953 | with self.msg.filter_errors(): |
| 2954 | if typ.param_spec() is not None: |
| 2955 | # ParamSpec can be expanded in a lot of different ways. We may try |
| 2956 | # to expand it here instead, but picking an impossible overload |
| 2957 | # is safe: it will be filtered out later. |
| 2958 | # Unlike other var-args signatures, ParamSpec produces essentially |
| 2959 | # a fixed signature, so there's no need to push them to the top. |
| 2960 | matches.append(typ) |
| 2961 | elif self.check_argument_count( |
| 2962 | typ, arg_types, arg_kinds, arg_names, formal_to_actual, None |
| 2963 | ): |
| 2964 | if args_have_var_arg and typ.is_var_arg: |
| 2965 | star_matches.append(typ) |
| 2966 | elif args_have_kw_arg and typ.is_kw_arg: |
| 2967 | star_matches.append(typ) |
| 2968 | else: |
| 2969 | matches.append(typ) |
| 2970 | |
| 2971 | return star_matches + matches |
no test coverage detected