Пример #1
0
    def infer_function_type_arguments_pass2(
                                 self, callee_type, args, arg_kinds, formal_to_actual, inferred_args, context):
        """Perform second pass of generic function type argument inference.

        The second pass is needed for arguments with types such as func<s(t)>,
        where both s and t are type variables, when the actual argument is a
        lambda with inferred types.  The idea is to infer the type variable t
        in the first pass (based on the types of other arguments).  This lets
        us infer the argument and return type of the lambda expression and
        thus also the type variable s in this second pass.

        Return (the callee with type vars applied, inferred actual arg types).
        """
        # None or erased types in inferred types mean that there was not enough
        # information to infer the argument. Replace them with None values so
        # that they are not applied yet below.
        for i, arg in enumerate(inferred_args):
            if isinstance(arg, NoneTyp) or isinstance(arg, ErasedType):
                inferred_args[i] = None

        callee_type = self.apply_generic_arguments(
            callee_type, inferred_args, context)
        arg_types = self.infer_arg_types_in_context2(
            callee_type, args, arg_kinds, formal_to_actual)

        inferred_args = infer_function_type_arguments(
            callee_type, arg_types, arg_kinds, formal_to_actual,
            self.chk.basic_types())

        return callee_type, inferred_args
Пример #2
0
    def infer_function_type_arguments(self, callee_type, args, arg_kinds, formal_to_actual, context):
        """Infer the type arguments for a generic callee type.

        Infer based on the types of arguments.

        Return a derived callable type that has the arguments applied (and
        stored as implicit type arguments).
        """
        if not self.chk.is_dynamic_function():
            # Disable type errors during type inference. There may be errors
            # due to partial available context information at this time, but
            # these errors can be safely ignored as the arguments will be
            # inferred again later.
            self.msg.disable_errors()
            
            arg_types = self.infer_arg_types_in_context2(
                callee_type, args, arg_kinds, formal_to_actual)
        
            self.msg.enable_errors()

            arg_pass_nums = self.get_arg_infer_passes(
                callee_type.arg_types, formal_to_actual, len(args))

            pass1_args = []
            for i, arg in enumerate(arg_types):
                if arg_pass_nums[i] > 1:
                    pass1_args.append(None)
                else:
                    pass1_args.append(arg)
            
            inferred_args = infer_function_type_arguments(
                callee_type, pass1_args, arg_kinds, formal_to_actual,
                self.chk.basic_types())

            if 2 in arg_pass_nums:
                # Second pass of type inference.
                (callee_type,
                 inferred_args) = self.infer_function_type_arguments_pass2(
                    callee_type, args, arg_kinds, formal_to_actual,
                    inferred_args, context)
        else:
            # In dynamically typed functions use implicit 'any' types for
            # type variables.
            inferred_args = [Any()] * len(callee_type.variables.items)
        return self.apply_inferred_arguments(callee_type, inferred_args,
                                             context)
Пример #3
0
                                    erased_ctx, self.chk.basic_types())
        # If all the inferred types are None types, do no type variable
        # substition.
        # TODO This is not nearly general enough. If a type has a None type
        #      component we should not use it. Also if some types are not-None
        #      we should only substitute them. Finally, using None types for
        #      this might not be optimal.
        some_not_none = False
        for i in range(len(args)):
            if not isinstance(args[i], NoneTyp):
                some_not_none = True
        if not some_not_none:
            return callable
        return (Callable)self.apply_generic_arguments(callable, args, [], None)
    
    Callable infer_function_type_arguments(self, Callable callee_type,
                                           Typ[] arg_types,
                                           int[] arg_kinds,
                                           int[][] formal_to_actual,
                                           Context context):
        """Infer the type arguments for a generic callee type.

        Return a derived callable type that has the arguments applied (and
        stored as implicit type arguments). If is_var_arg is True, the callee
        uses varargs.
        """
        Typ[] inferred_args = infer_function_type_arguments(
            callee_type, arg_types, arg_kinds, formal_to_actual,
            self.chk.basic_types())
        return self.apply_inferred_arguments(callee_type, inferred_args, [],
                                             context)