Ejemplo n.º 1
0
    def test_callable_type(self):
        c = Callable([self.x, self.y], [ARG_POS, ARG_POS], [None, None],
                     AnyType(), False)
        assert_equal(str(c), 'def (X?, Y?) -> Any')

        c2 = Callable([], [], [], Void(None), False)
        assert_equal(str(c2), 'def ()')
Ejemplo n.º 2
0
    def test_generic_function_type(self):
        c = Callable([self.x, self.y], [ARG_POS, ARG_POS], [None, None],
                     self.y, False, None, [TypeVarDef('X', -1, None)])
        assert_equal(str(c), 'def [X] (X?, Y?) -> Y?')

        v = [TypeVarDef('Y', -1, None), TypeVarDef('X', -2, None)]
        c2 = Callable([], [], [], Void(None), False, None, v)
        assert_equal(str(c2), 'def [Y, X] ()')
Ejemplo n.º 3
0
    def test_callable_type_with_default_args(self):
        c = Callable([self.x, self.y], [ARG_POS, ARG_OPT], [None, None],
                     AnyType(), False)
        assert_equal(str(c), 'def (X?, Y? =) -> Any')

        c2 = Callable([self.x, self.y], [ARG_OPT, ARG_OPT], [None, None],
                      AnyType(), False)
        assert_equal(str(c2), 'def (X? =, Y? =) -> Any')
Ejemplo n.º 4
0
    def test_callable_type_with_var_args(self):
        c = Callable([self.x], [ARG_STAR], [None], AnyType(), False)
        assert_equal(str(c), 'def (*X?) -> Any')

        c2 = Callable([self.x, self.y], [ARG_POS, ARG_STAR], [None, None],
                      AnyType(), False)
        assert_equal(str(c2), 'def (X?, *Y?) -> Any')

        c3 = Callable([self.x, self.y], [ARG_OPT, ARG_STAR], [None, None],
                      AnyType(), False)
        assert_equal(str(c3), 'def (X? =, *Y?) -> Any')
Ejemplo n.º 5
0
 def callable(self, *a):
     """callable(a1, ..., an, r) constructs a callable with argument types
     a1, ... an and return type r.
     """
     n = len(a) - 1
     return Callable(a[:-1], [ARG_POS] * n, [None] * n,
                     a[-1], False)
Ejemplo n.º 6
0
    def visit_callable(self, t: Callable) -> Type:
        res = Callable(self.anal_array(t.arg_types), t.arg_kinds, t.arg_names,
                       t.ret_type.accept(self), t.is_type_obj(), t.name,
                       self.anal_var_defs(t.variables),
                       self.anal_bound_vars(t.bound_vars), t.line, t.repr)

        return res
Ejemplo n.º 7
0
 def callable_type(self, *a):
     """callable_type(a1, ..., an, r) constructs a callable with
     argument types a1, ... an and return type r, and which
     represents a type.
     """
     return Callable(a[:-1], [ARG_POS] * (len(a) - 1),
                     [None] * (len(a) - 1), a[-1], True)
Ejemplo n.º 8
0
def dynamic_sig(sig: Callable) -> Callable:
    """Translate callable type to type erased (dynamically-typed) callable.

    Preserve the number and kinds of arguments.
    """
    return Callable([AnyType()] * len(sig.arg_types), sig.arg_kinds,
                    sig.arg_names, AnyType(), sig.is_type_obj())
Ejemplo n.º 9
0
def add_class_tvars(t: Type, info: TypeInfo, is_classmethod: bool,
                    builtin_type: Function[[str], Instance]) -> Type:
    if isinstance(t, Callable):
        # TODO: Should we propagate type variable values?
        vars = [
            TypeVarDef(n, i + 1, None, builtin_type('builtins.object'))
            for i, n in enumerate(info.type_vars)
        ]
        arg_types = t.arg_types
        arg_kinds = t.arg_kinds
        arg_names = t.arg_names
        if is_classmethod:
            arg_types = arg_types[1:]
            arg_kinds = arg_kinds[1:]
            arg_names = arg_names[1:]
        return Callable(arg_types, arg_kinds, arg_names, t.ret_type,
                        t.fallback, t.name, vars + t.variables, t.bound_vars,
                        t.line, None)
    elif isinstance(t, Overloaded):
        return Overloaded([
            cast(Callable,
                 add_class_tvars(i, info, is_classmethod, builtin_type))
            for i in t.items()
        ])
    return t
Ejemplo n.º 10
0
    def make_setter_wrapper(self, name: str, typ: Type) -> FuncDef:
        """Create a setter wrapper for a data attribute.

        The setter will be of this form:
        
        . def set$name(self: C, name: typ) -> None:
        .     self.name! = name
        """
        scope = self.make_scope()
        selft = self.self_type()
        selfv = scope.add('self', selft)
        namev = scope.add(name, typ)
        
        lvalue = MemberExpr(scope.name_expr('self'), name, direct=True)
        rvalue = scope.name_expr(name)
        ret = AssignmentStmt([lvalue], rvalue)

        wrapper_name = 'set$' + name
        sig = Callable([selft, typ],
                       [nodes.ARG_POS, nodes.ARG_POS],
                       [None, None],
                       Void(), False)
        fdef = FuncDef(wrapper_name,
                       [selfv, namev],
                       [nodes.ARG_POS, nodes.ARG_POS],
                       [None, None],
                       Block([ret]), sig)
        fdef.info = self.tf.type_context()
        return fdef
Ejemplo n.º 11
0
def parse_signature(tokens: List[Token]) -> Tuple[Callable, int]:
    """Parse signature of form (...) -> ...

    Return tuple (signature type, token index).
    """
    i = 0
    if tokens[i].string != '(':
        raise TypeParseError(tokens[i], i)
    i += 1
    arg_types = List[Type]()
    arg_kinds = List[int]()
    while tokens[i].string != ')':
        if tokens[i].string == '*':
            arg_kinds.append(nodes.ARG_STAR)
            i += 1
        elif tokens[i].string == '**':
            arg_kinds.append(nodes.ARG_STAR2)
            i += 1
        else:
            arg_kinds.append(nodes.ARG_POS)
        arg, i = parse_type(tokens, i)
        arg_types.append(arg)
        next = tokens[i].string
        if next not in ',)':
            raise TypeParseError(tokens[i], i)
        if next == ',':
            i += 1
    i += 1
    if tokens[i].string != '-' or tokens[i + 1].string != '>':
        raise TypeParseError(tokens[i], i)
    i += 2
    ret_type, i = parse_type(tokens, i)
    return Callable(arg_types, arg_kinds, [None] * len(arg_types), ret_type,
                    False), i
Ejemplo n.º 12
0
def add_arg_type_after_self(t: Callable, arg_type: Type) -> Callable:
    """Add an argument with the given type to a callable type after 'self'."""
    return Callable([t.arg_types[0], arg_type] + t.arg_types[1:],
                    [t.arg_kinds[0], nodes.ARG_POS] + t.arg_kinds[1:],
                    [t.arg_names[0], None] + t.arg_names[1:], t.ret_type,
                    t.is_type_obj(), t.name, t.variables, t.bound_vars, t.line,
                    None)
Ejemplo n.º 13
0
 def type_callable(self, *a):
     """type_callable(a1, ..., an, r) constructs a callable with
     argument types a1, ... an and return type r, and which
     represents a type.
     """
     n = len(a) - 1
     return Callable(a[:-1], [ARG_POS] * n, [None] * n,
                     a[-1], self.fx.type_type)
Ejemplo n.º 14
0
    def visit_callable(self, t: Callable) -> Type:
        res = Callable(self.anal_array(t.arg_types), t.arg_kinds, t.arg_names,
                       t.ret_type.accept(self),
                       self.builtin_type('builtins.function'), t.name,
                       self.anal_var_defs(t.variables),
                       self.anal_bound_vars(t.bound_vars), t.line, t.repr)

        return res
Ejemplo n.º 15
0
 def callable_var_arg(self, min_args, *a):
     """callable_var_arg(min_args, a1, ..., an, r) constructs a callable
     with argument types a1, ... *an and return type r.
     """
     n = len(a) - 1
     return Callable(a[:-1], [ARG_POS] * min_args + [ARG_OPT] *
                     (n - 1 - min_args) + [ARG_STAR], [None] * n, a[-1],
                     False)
Ejemplo n.º 16
0
 def callable_default(self, min_args, *a):
     """callable_default(min_args, a1, ..., an, r) constructs a
     callable with argument types a1, ... an and return type r,
     with min_args mandatory fixed arguments.
     """
     n = len(a) - 1
     return Callable(a[:-1],
                     [ARG_POS] * min_args + [ARG_OPT] * (n - min_args),
                     [None] * n, a[-1], False)
Ejemplo n.º 17
0
 def fix_bound_init_tvars(self, callable: Callable,
                          typ: Instance) -> Callable:
     """Replace bound type vars of callable with args from instance type."""
     a = [] # type: List[Tuple[int, Type]]
     for i in range(len(typ.args)):
         a.append((i + 1, typ.args[i]))
     return Callable(callable.arg_types, callable.arg_kinds,
                     callable.arg_names, callable.ret_type,
                     callable.is_type_obj(), callable.name,
                     callable.variables, a)
Ejemplo n.º 18
0
Archivo: join.py Proyecto: silky/mypy
def combine_similar_callables(t: Callable, s: Callable,
                              basic: BasicTypes) -> Callable:
    arg_types = []  # type: List[Type]
    for i in range(len(t.arg_types)):
        arg_types.append(join_types(t.arg_types[i], s.arg_types[i], basic))
    # TODO kinds and argument names
    return Callable(arg_types, t.arg_kinds, t.arg_names,
                    join_types(t.ret_type, s.ret_type, basic),
                    t.is_type_obj() and s.is_type_obj(), None, t.variables)
    return s
Ejemplo n.º 19
0
 def analyze_function_type(self, t: UnboundType) -> Type:
     if len(t.args) != 2:
         self.fail('Invalid function type', t)
     if not isinstance(t.args[0], TypeList):
         self.fail('Invalid function type', t)
         return AnyType()
     args = (cast(TypeList, t.args[0])).items
     return Callable(self.anal_array(args), [nodes.ARG_POS] * len(args),
                     [None] * len(args),
                     ret_type=t.args[1].accept(self),
                     fallback=self.builtin_type('builtins.function'))
Ejemplo n.º 20
0
 def callable(self, vars, *a) -> Callable:
     """callable(args, a1, ..., an, r) constructs a callable with
     argument types a1, ... an and return type r and type arguments
     vars.
     """
     tv = []  # type: List[TypeVarDef]
     n = -1
     for v in vars:
         tv.append(TypeVarDef(v, n, None))
         n -= 1
     return Callable(a[:-1], [ARG_POS] * (len(a) - 1),
                     [None] * (len(a) - 1), a[-1], False, None, tv)
Ejemplo n.º 21
0
def add_class_tvars(t: Type, info: TypeInfo) -> Type:
    if isinstance(t, Callable):
        vars = [
            TypeVarDef(n, i + 1, None) for i, n in enumerate(info.type_vars)
        ]
        return Callable(t.arg_types, t.arg_kinds, t.arg_names, t.ret_type,
                        t.is_type_obj(), t.name, vars + t.variables,
                        t.bound_vars, t.line, None)
    elif isinstance(t, Overloaded):
        return Overloaded(
            [cast(Callable, add_class_tvars(i, info)) for i in t.items()])
    return t
Ejemplo n.º 22
0
def class_callable(init_type: Callable, info: TypeInfo) -> Callable:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    for i, tvar in enumerate(info.defn.type_vars):
        variables.append(TypeVarDef(tvar.name, i + 1, tvar.values))

    initvars = init_type.variables
    variables.extend(initvars)

    c = Callable(init_type.arg_types, init_type.arg_kinds, init_type.arg_names,
                 self_type(info), True, None,
                 variables).with_name('"{}"'.format(info.name()))
    return convert_class_tvars_to_func_tvars(c, len(initvars))
Ejemplo n.º 23
0
def apply_generic_arguments(callable: Callable, types: List[Type],
                            msg: MessageBuilder, context: Context) -> Type:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def [-1:int] (int) -> int'. Here '[-1:int]' is an implicit bound type
    variable.

    Note that each type can be None; in this case, it will not be applied.
    """
    tvars = callable.variables
    if len(tvars) != len(types):
        msg.incompatible_type_application(len(tvars), len(types), context)
        return AnyType()

    # Check that inferred type variable values are compatible with allowed
    # values.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            for value in values:
                if mypy.subtypes.is_subtype(type, value):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, i + 1, type, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[int, Type]
    for i, tv in enumerate(tvars):
        if types[i]:
            id_to_type[tv.id] = types[i]

    # Apply arguments to argument types.
    arg_types = [expand_type(at, id_to_type) for at in callable.arg_types]

    bound_vars = [(tv.id, id_to_type[tv.id]) for tv in tvars
                  if tv.id in id_to_type]

    # The callable may retain some type vars if only some were applied.
    remaining_tvars = [tv for tv in tvars if tv.id not in id_to_type]

    return Callable(arg_types, callable.arg_kinds, callable.arg_names,
                    expand_type(callable.ret_type,
                                id_to_type), callable.fallback, callable.name,
                    remaining_tvars, callable.bound_vars + bound_vars,
                    callable.line, callable.repr)
Ejemplo n.º 24
0
    def make_generic_wrapper_init(self, info: TypeInfo) -> FuncDef:
        """Build constructor of a generic wrapper class."""
        nslots = num_slots(info)
        
        cdefs = [] # type: List[Node]
        
        # Build superclass constructor call.
        base = info.mro[1]
        if base.fullname() != 'builtins.object' and self.tf.is_java:
            s = SuperExpr('__init__')
            cargs = [NameExpr('__o')] # type: List[Node]
            for n in range(num_slots(base)):
                cargs.append(NameExpr(tvar_arg_name(n + 1)))
            for n in range(num_slots(base)):
                cargs.append(NameExpr(tvar_arg_name(n + 1, BOUND_VAR)))
            c = CallExpr(s, cargs, [nodes.ARG_POS] * len(cargs))
            cdefs.append(ExpressionStmt(c))
        
        # Create initialization of the wrapped object.
        cdefs.append(AssignmentStmt([MemberExpr(
                                         self_expr(),
                                         self.object_member_name(info),
                                         direct=True)],
                                    NameExpr('__o')))
        
        # Build constructor arguments.
        args = [Var('self'), Var('__o')]
        init = [None, None] # type: List[Node]
        
        for alt in [False, BOUND_VAR]:
            for n in range(nslots):
                args.append(Var(tvar_arg_name(n + 1, alt)))
                init.append(None)

        nargs = nslots * 2 + 2
        fdef = FuncDef('__init__',
                       args,
                       [nodes.ARG_POS] * nargs,
                       init,
                       Block(cdefs),
                       Callable( [AnyType()] * nargs,
                                [nodes.ARG_POS] * nargs, [None] * nargs,
                                Void(),
                                is_type_obj=False))
        fdef.info = info
        
        self.make_wrapper_slot_initializer(fdef)
        
        return fdef
Ejemplo n.º 25
0
def combine_similar_callables(t: Callable, s: Callable) -> Callable:
    arg_types = []  # type: List[Type]
    for i in range(len(t.arg_types)):
        arg_types.append(join_types(t.arg_types[i], s.arg_types[i]))
    # TODO kinds and argument names
    # The fallback type can be either 'function' or 'type'. The result should have 'type' as
    # fallback only if both operands have it as 'type'.
    if t.fallback.type.fullname() != 'builtins.type':
        fallback = t.fallback
    else:
        fallback = s.fallback
    return Callable(arg_types,
                    t.arg_kinds,
                    t.arg_names,
                    join_types(t.ret_type, s.ret_type),
                    fallback,
                    None,
                    t.variables)
    return s
Ejemplo n.º 26
0
    def make_type_object_wrapper(self, tdef: ClassDef) -> FuncDef:
        """Construct dynamically typed wrapper function for a class.

        It simple calls the type object and returns the result.
        """
        
        # TODO keyword args, default args and varargs
        # TODO overloads

        type_sig = cast(Callable, type_object_type(tdef.info, None))
        type_sig = cast(Callable, erasetype.erase_typevars(type_sig))
        
        init = cast(FuncDef, tdef.info.get_method('__init__'))
        arg_kinds = type_sig.arg_kinds

        # The wrapper function has a dynamically typed signature.
        wrapper_sig = Callable( [AnyType()] * len(arg_kinds),
                               arg_kinds, [None] * len(arg_kinds),
                               AnyType(), False)
        
        n = NameExpr(tdef.name) # TODO full name
        args = self.func_tf.call_args(
            init.args[1:],
            type_sig,
            wrapper_sig,
            True, False)
        call = CallExpr(n, args, arg_kinds)
        ret = ReturnStmt(call)
        

        fdef = FuncDef(tdef.name + self.tf.dynamic_suffix(),
                       init.args[1:],
                       arg_kinds, [None] * len(arg_kinds),
                       Block([ret]))
        
        fdef.type = wrapper_sig
        return fdef
Ejemplo n.º 27
0
    def make_getter_wrapper(self, name: str, typ: Type) -> FuncDef:
        """Create a getter wrapper for a data attribute.

        The getter will be of this form:
        
        . def $name*(self: C) -> type:
        .     return self.name!
        """
        scope = self.make_scope()
        selft = self.self_type()
        selfv = scope.add('self', selft)
        
        member_expr = MemberExpr(scope.name_expr('self'), name, direct=True)
        ret = ReturnStmt(member_expr)

        wrapper_name = '$' + name
        sig = Callable([selft], [nodes.ARG_POS], [None], typ, False)
        fdef = FuncDef(wrapper_name,
                       [selfv],
                       [nodes.ARG_POS],
                       [None],
                       Block([ret]), sig)
        fdef.info = self.tf.type_context()
        return fdef
Ejemplo n.º 28
0
    def make_dynamic_getter_wrapper(self, name: str, typ: Type) -> FuncDef:
        """Create a dynamically-typed getter wrapper for a data attribute.

        The getter will be of this form:
        
        . def $name*(self: C) -> Any:
        .     return {Any <= typ self.name!}
        """
        scope = self.make_scope()
        selft = self.self_type()
        selfv = scope.add('self', selft)
        
        member_expr = MemberExpr(scope.name_expr('self'), name, direct=True)
        coerce_expr = coerce(member_expr, AnyType(), typ,
                             self.tf.type_context())
        ret = ReturnStmt(coerce_expr)

        wrapper_name = '$' + name + self.tf.dynamic_suffix()
        sig = Callable([selft], [nodes.ARG_POS], [None], AnyType(), False)
        return FuncDef(wrapper_name,
                       [selfv],
                       [nodes.ARG_POS],
                       [None],
                       Block([ret]), sig)
Ejemplo n.º 29
0
    def make_dynamic_setter_wrapper(self, name: str, typ: Type) -> FuncDef:
        """Create a dynamically-typed setter wrapper for a data attribute.

        The setter will be of this form:
        
        . def set$name*(self: C, name; Any) -> None:
        .     self.name! = {typ name}
        """
        lvalue = MemberExpr(self_expr(), name, direct=True)
        name_expr = NameExpr(name)
        rvalue = coerce(name_expr, typ, AnyType(), self.tf.type_context())
        ret = AssignmentStmt([lvalue], rvalue)

        wrapper_name = 'set$' + name + self.tf.dynamic_suffix()
        selft = self_type(self.tf.type_context())            
        sig = Callable([selft, AnyType()],
                       [nodes.ARG_POS, nodes.ARG_POS],
                       [None, None],
                       Void(), False)
        return FuncDef(wrapper_name,
                       [Var('self'), Var(name)],
                       [nodes.ARG_POS, nodes.ARG_POS],
                       [None, None],
                       Block([ret]), sig)
Ejemplo n.º 30
0
 def visit_callable(self, t: Callable) -> Type:
     return Callable(self.expand_types(t.arg_types),
                     t.arg_kinds, t.arg_names, t.ret_type.accept(self),
                     t.is_type_obj(), t.name, t.variables,
                     self.expand_bound_vars(t.bound_vars), t.line, t.repr)