Beispiel #1
0
 def default(self, typ):
     if isinstance(typ, UnboundType):
         return AnyType()
     elif isinstance(typ, Void) or isinstance(typ, ErrorType):
         return ErrorType()
     else:
         return NoneTyp()
Beispiel #2
0
def make_optional_type(t: Type) -> Type:
    """Return the type corresponding to Optional[t].

    Note that we can't use normal union simplification, since this function
    is called during semantic analysis and simplification only works during
    type checking.
    """
    if isinstance(t, NoneTyp):
        return t
    elif isinstance(t, UnionType):
        items = [
            item for item in union_items(t) if not isinstance(item, NoneTyp)
        ]
        return UnionType(items + [NoneTyp()], t.line, t.column)
    else:
        return UnionType([t, NoneTyp()], t.line, t.column)
Beispiel #3
0
    def test_callable_type(self) -> None:
        c = CallableType([self.x, self.y], [ARG_POS, ARG_POS], [None, None],
                         AnyType(TypeOfAny.special_form), self.function)
        assert_equal(str(c), 'def (X?, Y?) -> Any')

        c2 = CallableType([], [], [], NoneTyp(), self.fx.function)
        assert_equal(str(c2), 'def ()')
Beispiel #4
0
def typed_dict_get_callback(ctx: MethodContext) -> Type:
    """Infer a precise return type for TypedDict.get with literal first argument."""
    if (isinstance(ctx.type, TypedDictType) and len(ctx.arg_types) >= 1
            and len(ctx.arg_types[0]) == 1):
        key = try_getting_str_literal(ctx.args[0][0], ctx.arg_types[0][0])
        if key is None:
            return ctx.default_return_type

        value_type = ctx.type.items.get(key)
        if value_type:
            if len(ctx.arg_types) == 1:
                return UnionType.make_simplified_union([value_type, NoneTyp()])
            elif (len(ctx.arg_types) == 2 and len(ctx.arg_types[1]) == 1
                  and len(ctx.args[1]) == 1):
                default_arg = ctx.args[1][0]
                if (isinstance(default_arg, DictExpr)
                        and len(default_arg.items) == 0
                        and isinstance(value_type, TypedDictType)):
                    # Special case '{}' as the default for a typed dict type.
                    return value_type.copy_modified(required_keys=set())
                else:
                    return UnionType.make_simplified_union(
                        [value_type, ctx.arg_types[1][0]])
        else:
            ctx.api.msg.typeddict_key_not_found(ctx.type, key, ctx.context)
            return AnyType(TypeOfAny.from_error)
    return ctx.default_return_type
Beispiel #5
0
def _autoconvertible_to_cdata(
        tp: Type, api: 'mypy.plugin.CheckerPluginInterface') -> Type:
    """Get a type that is compatible with all types that can be implicitly converted to the given
    CData type.

    Examples:
    * c_int -> Union[c_int, int]
    * c_char_p -> Union[c_char_p, bytes, int, NoneType]
    * MyStructure -> MyStructure
    """
    allowed_types = []
    # If tp is a union, we allow all types that are convertible to at least one of the union
    # items. This is not quite correct - strictly speaking, only types convertible to *all* of the
    # union items should be allowed. This may be worth changing in the future, but the more
    # correct algorithm could be too strict to be useful.
    for t in union_items(tp):
        # Every type can be converted from itself (obviously).
        allowed_types.append(t)
        if isinstance(t, Instance):
            unboxed = _find_simplecdata_base_arg(t, api)
            if unboxed is not None:
                # If _SimpleCData appears in tp's (direct or indirect) bases, its type argument
                # specifies the type's "unboxed" version, which can always be converted back to
                # the original "boxed" type.
                allowed_types.append(unboxed)

                if t.type.has_base('ctypes._PointerLike'):
                    # Pointer-like _SimpleCData subclasses can also be converted from
                    # an int or None.
                    allowed_types.append(
                        api.named_generic_type('builtins.int', []))
                    allowed_types.append(NoneTyp())

    return UnionType.make_simplified_union(allowed_types)
Beispiel #6
0
def column_hook(ctx: FunctionContext) -> Type:
    """Infer better types for Column calls.

    Examples:
        Column(String) -> Column[Optional[str]]
        Column(String, primary_key=True) -> Column[str]
        Column(String, nullable=False) -> Column[str]
        Column(String, default=...) -> Column[str]
        Column(String, default=..., nullable=True) -> Column[Optional[str]]

    TODO: check the type of 'default'.
    """
    assert isinstance(ctx.default_return_type, Instance)

    nullable_arg = get_argument_by_name(ctx, 'nullable')
    primary_arg = get_argument_by_name(ctx, 'primary_key')
    default_arg = get_argument_by_name(ctx, 'default')

    if nullable_arg:
        nullable = parse_bool(nullable_arg)
    else:
        if primary_arg:
            nullable = not parse_bool(primary_arg)
        else:
            nullable = default_arg is None
    # TODO: Add support for literal types.

    if not nullable:
        return ctx.default_return_type
    assert len(ctx.default_return_type.args) == 1
    arg_type = ctx.default_return_type.args[0]
    return Instance(ctx.default_return_type.type, [UnionType([arg_type, NoneTyp()])],
                    line=ctx.default_return_type.line,
                    column=ctx.default_return_type.column)
Beispiel #7
0
def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
    """Return the declared type narrowed down to another type."""
    if declared == narrowed:
        return declared
    if isinstance(declared, UnionType):
        return UnionType.make_simplified_union([
            narrow_declared_type(x, narrowed)
            for x in declared.relevant_items()
        ])
    elif not is_overlapping_types(
            declared, narrowed, prohibit_none_typevar_overlap=True):
        if state.strict_optional:
            return UninhabitedType()
        else:
            return NoneTyp()
    elif isinstance(narrowed, UnionType):
        return UnionType.make_simplified_union([
            narrow_declared_type(declared, x)
            for x in narrowed.relevant_items()
        ])
    elif isinstance(narrowed, AnyType):
        return narrowed
    elif isinstance(declared, (Instance, TupleType)):
        return meet_types(declared, narrowed)
    elif isinstance(declared, TypeType) and isinstance(narrowed, TypeType):
        return TypeType.make_normalized(
            narrow_declared_type(declared.item, narrowed.item))
    return narrowed
def add_model_init_hook(ctx: ClassDefContext) -> None:
    """Add a dummy __init__() to a model and record it is generated.

    Instantiation will be checked more precisely when we inferred types
    (using get_function_hook and model_hook).
    """
    if '__init__' in ctx.cls.info.names:
        # Don't override existing definition.
        return
    any = AnyType(TypeOfAny.special_form)
    var = Var('kwargs', any)
    kw_arg = Argument(variable=var,
                      type_annotation=any,
                      initializer=None,
                      kind=ARG_STAR2)
    add_method(ctx, '__init__', [kw_arg], NoneTyp())
    ctx.cls.info.metadata.setdefault('sqlalchemy', {})['generated_init'] = True

    # Also add a selection of auto-generated attributes.
    sym = ctx.api.lookup_fully_qualified_or_none('sqlalchemy.sql.schema.Table')
    if sym:
        assert isinstance(sym.node, TypeInfo)
        typ = Instance(sym.node, [])  # type: Type
    else:
        typ = AnyType(TypeOfAny.special_form)
    add_var_to_class('__table__', typ, ctx.cls.info)
Beispiel #9
0
Datei: meet.py Projekt: scop/mypy
def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
    """Return the declared type narrowed down to another type."""
    if declared == narrowed:
        return declared
    if isinstance(declared, UnionType):
        return UnionType.make_simplified_union([
            narrow_declared_type(x, narrowed)
            for x in declared.relevant_items()
        ])
    elif not is_overlapping_types(declared, narrowed, use_promotions=True):
        if experiments.STRICT_OPTIONAL:
            return UninhabitedType()
        else:
            return NoneTyp()
    elif isinstance(narrowed, UnionType):
        return UnionType.make_simplified_union([
            narrow_declared_type(declared, x)
            for x in narrowed.relevant_items()
        ])
    elif isinstance(narrowed, AnyType):
        return narrowed
    elif isinstance(declared, (Instance, TupleType)):
        return meet_types(declared, narrowed)
    elif isinstance(declared, TypeType) and isinstance(narrowed, TypeType):
        return TypeType.make_normalized(
            narrow_declared_type(declared.item, narrowed.item))
    return narrowed
Beispiel #10
0
        def analyze_interface_base(classdef_ctx: ClassDefContext) -> None:
            # Create fake constructor to mimic adaptation signature
            info = classdef_ctx.cls.info
            api = classdef_ctx.api
            if "__init__" in info.names:
                # already patched
                return

            # Create a method:
            #
            # def __init__(self, obj, alternate=None) -> None
            #
            # This will make interfaces
            selftp = Instance(info, [])
            anytp = AnyType(TypeOfAny.implementation_artifact)
            init_fn = CallableType(
                arg_types=[selftp, anytp, anytp],
                arg_kinds=[ARG_POS, ARG_POS, ARG_OPT],
                arg_names=["self", "obj", "alternate"],
                ret_type=NoneTyp(),
                fallback=api.named_type("function"),
            )
            newinit = FuncDef("__init__", [], Block([]), init_fn)
            newinit.info = info
            info.names["__init__"] = SymbolTableNode(
                MDEF, newinit, plugin_generated=True
            )
Beispiel #11
0
 def default(self, typ: Type) -> Type:
     if isinstance(typ, UnboundType):
         return AnyType(TypeOfAny.special_form)
     else:
         if experiments.STRICT_OPTIONAL:
             return UninhabitedType()
         else:
             return NoneTyp()
Beispiel #12
0
def _add_init(ctx: 'mypy.plugin.ClassDefContext', attributes: List[Attribute],
              adder: 'MethodAdder') -> None:
    """Generate an __init__ method for the attributes and add it to the class."""
    adder.add_method(
        '__init__',
        [attribute.argument(ctx) for attribute in attributes if attribute.init],
        NoneTyp()
    )
Beispiel #13
0
 def default(self, typ: Type) -> Type:
     if isinstance(typ, UnboundType):
         return AnyType(TypeOfAny.special_form)
     else:
         if state.strict_optional:
             return UninhabitedType()
         else:
             return NoneTyp()
Beispiel #14
0
    def test_error_type(self):
        self.assert_meet(self.fx.err, self.fx.anyt, self.fx.err)

        # Meet against any type except dynamic results in ErrorType.
        for t in [self.fx.a, self.fx.o, NoneTyp(), UnboundType('x'),
                  self.fx.void, self.fx.t, self.tuple(),
                  self.callable(self.fx.a, self.fx.b)]:
            self.assert_meet(t, self.fx.err, self.fx.err)
Beispiel #15
0
def solve_constraints(vars: List[int], constraints: List[Constraint],
                      basic: BasicTypes) -> List[Type]:
    """Solve type constraints.

    Return the best type(s) for type variables; each type can be None if the value of the variable
    could not be solved. If a variable has no constraints, arbitrarily pick NoneTyp as the value of
    the type variable.
    """
    # Collect a list of constraints for each type variable.
    cmap = Dict[int, List[Constraint]]()
    for con in constraints:
        a = cmap.get(con.type_var, [])
        a.append(con)
        cmap[con.type_var] = a

    res = []  # type: List[Type]

    # Solve each type variable separately.
    for tvar in vars:
        bottom = None  # type: Type
        top = None  # type: Type

        # Process each contraint separely, and calculate the lower and upper
        # bounds based on constraints. Note that we assume that the constraint
        # targets do not have constraint references.
        for c in cmap.get(tvar, []):
            if c.op == SUPERTYPE_OF:
                if bottom is None:
                    bottom = c.target
                else:
                    bottom = join_types(bottom, c.target, basic)
            else:
                if top is None:
                    top = c.target
                else:
                    top = meet_types(top, c.target, basic)

        if isinstance(top, AnyType) or isinstance(bottom, AnyType):
            res.append(AnyType())
            continue
        elif bottom is None:
            if top:
                candidate = top
            else:
                # No constraints for type variable -- type 'None' is the most specific type.
                candidate = NoneTyp()
        elif top is None:
            candidate = bottom
        elif is_subtype(bottom, top):
            candidate = bottom
        else:
            candidate = None
        if isinstance(candidate, ErrorType):
            res.append(None)
        else:
            res.append(candidate)

    return res
Beispiel #16
0
    def test_none(self):
        self.assert_meet(NoneTyp(), NoneTyp(), NoneTyp())

        self.assert_meet(NoneTyp(), self.fx.anyt, NoneTyp())
        self.assert_meet(NoneTyp(), self.fx.void, self.fx.err)

        # Any type t joined with None results in None, unless t is any or
        # void.
        for t in [self.fx.a, self.fx.o, UnboundType('x'), self.fx.t,
                  self.tuple(), self.callable(self.fx.a, self.fx.b)]:
            self.assert_meet(t, NoneTyp(), NoneTyp())
Beispiel #17
0
    def test_generic_function_type(self) -> None:
        c = CallableType([self.x, self.y], [ARG_POS, ARG_POS], [None, None],
                     self.y, self.function, name=None,
                     variables=[TypeVarDef('X', 'X', -1, [], self.fx.o)])
        assert_equal(str(c), 'def [X] (X?, Y?) -> Y?')

        v = [TypeVarDef('Y', 'Y', -1, [], self.fx.o),
             TypeVarDef('X', 'X', -2, [], self.fx.o)]
        c2 = CallableType([], [], [], NoneTyp(), self.function, name=None, variables=v)
        assert_equal(str(c2), 'def [Y, X] ()')
Beispiel #18
0
    def test_void(self):
        self.assert_join(self.fx.void, self.fx.void, self.fx.void)
        self.assert_join(self.fx.void, self.fx.anyt, self.fx.anyt)

        # Join of any other type against void results in ErrorType, since there
        # is no other meaningful result.
        for t in [self.fx.a, self.fx.o, NoneTyp(), UnboundType('x'),
                  self.fx.t, self.tuple(),
                  self.callable(self.fx.a, self.fx.b)]:
            self.assert_join(t, self.fx.void, self.fx.err)
Beispiel #19
0
 def default(self, typ):
     if isinstance(typ, UnboundType):
         return AnyType()
     elif isinstance(typ, Void) or isinstance(typ, ErrorType):
         return ErrorType()
     else:
         if experiments.STRICT_OPTIONAL:
             return UninhabitedType()
         else:
             return NoneTyp()
Beispiel #20
0
    def test_void(self):
        self.assert_meet(self.fx.void, self.fx.void, self.fx.void)
        self.assert_meet(self.fx.void, self.fx.anyt, self.fx.void)

        # Meet of any other type against void results in ErrorType, since there
        # is no meaningful valid result.
        for t in [self.fx.a, self.fx.o, UnboundType('x'), NoneTyp(),
                  self.fx.t, self.tuple(),
                  self.callable(self.fx.a, self.fx.b)]:
            self.assert_meet(t, self.fx.void, self.fx.err)
Beispiel #21
0
 def test_dynamic_type(self):
     # Meet against dynamic type always results in dynamic.
     for t in [
             self.fx.anyt, self.fx.a, self.fx.o,
             NoneTyp(),
             UnboundType('x'), self.fx.void, self.fx.t,
             self.tuple(),
             self.callable(self.fx.a, self.fx.b)
     ]:
         self.assert_meet(t, self.fx.anyt, t)
Beispiel #22
0
def join_type_list(types: List[Type]) -> Type:
    if not types:
        # This is a little arbitrary but reasonable. Any empty tuple should be compatible
        # with all variable length tuples, and this makes it possible. A better approach
        # would be to use a special bottom type.
        return NoneTyp()
    joined = types[0]
    for t in types[1:]:
        joined = join_types(joined, t)
    return joined
Beispiel #23
0
def add_init_to_cls(ctx: ClassDefContext) -> None:
    if "__init__" not in ctx.cls.info.names:
        anytype = AnyType(TypeOfAny.special_form)
        var = Var("kwargs", anytype)
        kw_arg = Argument(variable=var,
                          type_annotation=anytype,
                          initializer=None,
                          kind=ARG_STAR2)
        add_method(ctx, "__init__", [kw_arg], NoneTyp())
    set_declarative(ctx.cls.info)
Beispiel #24
0
 def test_any_type(self):
     # Join against 'Any' type always results in 'Any'.
     for t in [
             self.fx.anyt, self.fx.a, self.fx.o,
             NoneTyp(),
             UnboundType('x'), self.fx.void, self.fx.t,
             self.tuple(),
             self.callable(self.fx.a, self.fx.b)
     ]:
         self.assert_join(t, self.fx.anyt, self.fx.anyt)
Beispiel #25
0
    def build_newtype_typeinfo(self, name: str, old_type: Type, base_type: Instance) -> TypeInfo:
        info = self.api.basic_new_typeinfo(name, base_type)
        info.is_newtype = True

        # Add __init__ method
        args = [Argument(Var('self'), NoneTyp(), None, ARG_POS),
                self.make_argument('item', old_type)]
        signature = CallableType(
            arg_types=[Instance(info, []), old_type],
            arg_kinds=[arg.kind for arg in args],
            arg_names=['self', 'item'],
            ret_type=NoneTyp(),
            fallback=self.api.named_type('__builtins__.function'),
            name=name)
        init_func = FuncDef('__init__', args, Block([]), typ=signature)
        init_func.info = info
        init_func._fullname = self.api.qualified_name(name) + '.__init__'
        info.names['__init__'] = SymbolTableNode(MDEF, init_func)

        return info
Beispiel #26
0
def proper_types_hook(ctx: FunctionContext) -> Type:
    """Check if this get_proper_types() call is not redundant."""
    arg_types = ctx.arg_types[0]
    if arg_types:
        arg_type = arg_types[0]
        proper_type = get_proper_type_instance(ctx)
        item_type = UnionType.make_union([NoneTyp(), proper_type])
        ok_type = ctx.api.named_generic_type('typing.Iterable', [item_type])
        if is_proper_subtype(arg_type, ok_type):
            ctx.api.fail('Redundant call to get_proper_types()', ctx.context)
    return ctx.default_return_type
Beispiel #27
0
def handle_partial_attribute_type(typ: PartialType, is_lvalue: bool, msg: MessageBuilder,
                                  context: Context) -> Type:
    if typ.type is None:
        # 'None' partial type. It has a well-defined type -- 'None'.
        # In an lvalue context we want to preserver the knowledge of
        # it being a partial type.
        if not is_lvalue:
            return NoneTyp()
        return typ
    else:
        msg.fail(messages.NEED_ANNOTATION_FOR_VAR, context)
        return AnyType()
Beispiel #28
0
def handle_partial_attribute_type(typ: PartialType, is_lvalue: bool, msg: MessageBuilder,
                                  node: SymbolNode) -> Type:
    if typ.type is None:
        # 'None' partial type. It has a well-defined type -- 'None'.
        # In an lvalue context we want to preserver the knowledge of
        # it being a partial type.
        if not is_lvalue:
            return NoneTyp()
        return typ
    else:
        msg.need_annotation_for_var(node, node)
        return AnyType(TypeOfAny.from_error)
Beispiel #29
0
def meet_simple(s: Type, t: Type, default_right: bool = True) -> Type:
    if s == t:
        return s
    if isinstance(s, UnionType):
        return UnionType.make_simplified_union([meet_types(x, t) for x in s.items])
    elif not is_overlapping_types(s, t, use_promotions=True):
        return NoneTyp()
    else:
        if default_right:
            return t
        else:
            return s
Beispiel #30
0
def proper_type_hook(ctx: FunctionContext) -> Type:
    """Check if this get_proper_type() call is not redundant."""
    arg_types = ctx.arg_types[0]
    if arg_types:
        arg_type = get_proper_type(arg_types[0])
        proper_type = get_proper_type_instance(ctx)
        if is_proper_subtype(arg_type, UnionType.make_union([NoneTyp(), proper_type])):
            # Minimize amount of spurious errors from overload machinery.
            # TODO: call the hook on the overload as a whole?
            if isinstance(arg_type, (UnionType, Instance)):
                ctx.api.fail('Redundant call to get_proper_type()', ctx.context)
    return ctx.default_return_type