Beispiel #1
0
 def analyze_callable_args(self, arglist: TypeList) -> Optional[Tuple[List[Type],
                                                                      List[int],
                                                                      List[Optional[str]]]]:
     args = []   # type: List[Type]
     kinds = []  # type: List[int]
     names = []  # type: List[str]
     for arg in arglist.items:
         if isinstance(arg, CallableArgument):
             args.append(arg.typ)
             names.append(arg.name)
             if arg.constructor is None:
                 return None
             found = self.lookup(arg.constructor, arg)
             if found is None:
                 # Looking it up already put an error message in
                 return None
             elif found.fullname not in ARG_KINDS_BY_CONSTRUCTOR:
                 self.fail('Invalid argument constructor "{}"'.format(
                     found.fullname), arg)
                 return None
             else:
                 kind = ARG_KINDS_BY_CONSTRUCTOR[found.fullname]
                 kinds.append(kind)
                 if arg.name is not None and kind in {ARG_STAR, ARG_STAR2}:
                     self.fail("{} arguments should not have names".format(
                         arg.constructor), arg)
                     return None
         else:
             args.append(arg)
             kinds.append(ARG_POS)
             names.append(None)
     # Note that arglist below is only used for error context.
     check_arg_names(names, [arglist] * len(args), self.fail, "Callable")
     check_arg_kinds(kinds, [arglist] * len(args), self.fail)
     return args, kinds, names
Beispiel #2
0
 def analyze_callable_args(self, arglist: TypeList) -> Optional[Tuple[List[Type],
                                                                      List[int],
                                                                      List[Optional[str]]]]:
     args = []   # type: List[Type]
     kinds = []  # type: List[int]
     names = []  # type: List[Optional[str]]
     for arg in arglist.items:
         if isinstance(arg, CallableArgument):
             args.append(arg.typ)
             names.append(arg.name)
             if arg.constructor is None:
                 return None
             found = self.lookup(arg.constructor, arg)
             if found is None:
                 # Looking it up already put an error message in
                 return None
             elif found.fullname not in ARG_KINDS_BY_CONSTRUCTOR:
                 self.fail('Invalid argument constructor "{}"'.format(
                     found.fullname), arg)
                 return None
             else:
                 assert found.fullname is not None
                 kind = ARG_KINDS_BY_CONSTRUCTOR[found.fullname]
                 kinds.append(kind)
                 if arg.name is not None and kind in {ARG_STAR, ARG_STAR2}:
                     self.fail("{} arguments should not have names".format(
                         arg.constructor), arg)
                     return None
         else:
             args.append(arg)
             kinds.append(ARG_POS)
             names.append(None)
     # Note that arglist below is only used for error context.
     check_arg_names(names, [arglist] * len(args), self.fail, "Callable")
     check_arg_kinds(kinds, [arglist] * len(args), self.fail)
     return args, kinds, names
Beispiel #3
0
    def analyze_callable_type(self, t: UnboundType) -> Type:
        fallback = self.builtin_type('builtins.function')
        if len(t.args) == 0:
            # Callable (bare). Treat as Callable[..., Any].
            ret = CallableType([AnyType(), AnyType()],
                               [nodes.ARG_STAR, nodes.ARG_STAR2], [None, None],
                               ret_type=AnyType(),
                               fallback=fallback,
                               is_ellipsis_args=True)
        elif len(t.args) == 2:
            ret_type = t.args[1]
            if isinstance(t.args[0], TypeList):
                # Callable[[ARG, ...], RET] (ordinary callable type)
                args = []  # type: List[Type]
                names = []  # type: List[str]
                kinds = []  # type: List[int]
                for arg in t.args[0].items:
                    if isinstance(arg, CallableArgument):
                        args.append(arg.typ)
                        names.append(arg.name)
                        if arg.constructor is None:
                            return AnyType()
                        found = self.lookup(arg.constructor, arg)
                        if found is None:
                            # Looking it up already put an error message in
                            return AnyType()
                        elif found.fullname not in ARG_KINDS_BY_CONSTRUCTOR:
                            self.fail(
                                'Invalid argument constructor "{}"'.format(
                                    found.fullname), arg)
                            return AnyType()
                        else:
                            kind = ARG_KINDS_BY_CONSTRUCTOR[found.fullname]
                            kinds.append(kind)
                            if arg.name is not None and kind in {
                                    ARG_STAR, ARG_STAR2
                            }:
                                self.fail(
                                    "{} arguments should not have names".
                                    format(arg.constructor), arg)
                                return AnyType()
                    else:
                        args.append(arg)
                        names.append(None)
                        kinds.append(ARG_POS)

                check_arg_names(names, [t] * len(args), self.fail, "Callable")
                check_arg_kinds(kinds, [t] * len(args), self.fail)
                ret = CallableType(args,
                                   kinds,
                                   names,
                                   ret_type=ret_type,
                                   fallback=fallback)
            elif isinstance(t.args[0], EllipsisType):
                # Callable[..., RET] (with literal ellipsis; accept arbitrary arguments)
                ret = CallableType([AnyType(), AnyType()],
                                   [nodes.ARG_STAR, nodes.ARG_STAR2],
                                   [None, None],
                                   ret_type=ret_type,
                                   fallback=fallback,
                                   is_ellipsis_args=True)
            else:
                self.fail(
                    'The first argument to Callable must be a list of types or "..."',
                    t)
                return AnyType()
        else:
            self.fail('Invalid function type', t)
            return AnyType()
        assert isinstance(ret, CallableType)
        return ret.accept(self)