Пример #1
0
 def visit_instance(self, t: Instance) -> Type:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 for i in range(len(t.args)):
                     args.append(self.meet(t.args[i], si.args[i]))
                 return Instance(t.type, args)
             else:
                 if experiments.STRICT_OPTIONAL:
                     return UninhabitedType()
                 else:
                     return NoneTyp()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if experiments.STRICT_OPTIONAL:
                     return UninhabitedType()
                 else:
                     return NoneTyp()
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     else:
         return self.default(self.s)
Пример #2
0
    def test_is_proper_subtype_and_subtype_literal_types(self) -> None:
        fx = self.fx

        lit1 = LiteralType(1, fx.a)
        lit2 = LiteralType("foo", fx.d)
        lit3 = LiteralType("bar", fx.d)

        assert_true(is_proper_subtype(lit1, fx.a))
        assert_false(is_proper_subtype(lit1, fx.d))
        assert_false(is_proper_subtype(fx.a, lit1))
        assert_true(is_proper_subtype(fx.uninhabited, lit1))
        assert_false(is_proper_subtype(lit1, fx.uninhabited))
        assert_true(is_proper_subtype(lit1, lit1))
        assert_false(is_proper_subtype(lit1, lit2))
        assert_false(is_proper_subtype(lit2, lit3))

        assert_true(is_subtype(lit1, fx.a))
        assert_false(is_subtype(lit1, fx.d))
        assert_false(is_subtype(fx.a, lit1))
        assert_true(is_subtype(fx.uninhabited, lit1))
        assert_false(is_subtype(lit1, fx.uninhabited))
        assert_true(is_subtype(lit1, lit1))
        assert_false(is_subtype(lit1, lit2))
        assert_false(is_subtype(lit2, lit3))

        assert_false(is_proper_subtype(lit1, fx.anyt))
        assert_false(is_proper_subtype(fx.anyt, lit1))

        assert_true(is_subtype(lit1, fx.anyt))
        assert_true(is_subtype(fx.anyt, lit1))
Пример #3
0
def join_simple(declaration: Type, s: Type, t: Type) -> Type:
    """Return a simple least upper bound given the declared type."""

    if isinstance(s, AnyType):
        return s

    if isinstance(s, NoneTyp) and not isinstance(t, Void):
        return t

    if isinstance(s, ErasedType):
        return t

    if is_subtype(s, t):
        return t

    if is_subtype(t, s):
        return s

    if isinstance(declaration, UnionType):
        return UnionType.make_simplified_union([s, t])

    value = t.accept(TypeJoinVisitor(s))

    if value is None:
        # XXX this code path probably should be avoided.
        # It seems to happen when a line (x = y) is a type error, and
        # it's not clear that assuming that x is arbitrary afterward
        # is a good idea.
        return declaration

    if declaration is None or is_subtype(value, declaration):
        return value

    return declaration
Пример #4
0
def join_instances(t: Instance, s: Instance) -> Type:
    """Calculate the join of two instance types.

    If allow_interfaces is True, also consider interface-type results for
    non-interface types.

    Return ErrorType if the result is ambiguous.
    """

    if t.type == s.type:
        # Simplest case: join two types with the same base type (but
        # potentially different arguments).
        if is_subtype(t, s) or is_subtype(s, t):
            # Compatible; combine type arguments.
            args = []  # type: List[Type]
            for i in range(len(t.args)):
                args.append(join_types(t.args[i], s.args[i]))
            return Instance(t.type, args)
        else:
            # Incompatible; return trivial result object.
            return object_from_instance(t)
    elif t.type.bases and is_subtype_ignoring_tvars(t, s):
        return join_instances_via_supertype(t, s)
    else:
        # Now t is not a subtype of s, and t != s. Now s could be a subtype
        # of t; alternatively, we need to find a common supertype. This works
        # in of the both cases.
        return join_instances_via_supertype(s, t)
Пример #5
0
def array_constructor_callback(ctx: 'mypy.plugin.FunctionContext') -> Type:
    """Callback to provide an accurate signature for the ctypes.Array constructor."""
    # Extract the element type from the constructor's return type, i. e. the type of the array
    # being constructed.
    et = _get_array_element_type(ctx.default_return_type)
    if et is not None:
        allowed = _autoconvertible_to_cdata(et, ctx.api)
        assert len(ctx.arg_types) == 1, \
            "The stub of the ctypes.Array constructor should have a single vararg parameter"
        for arg_num, (arg_kind, arg_type) in enumerate(zip(ctx.arg_kinds[0], ctx.arg_types[0]), 1):
            if arg_kind == nodes.ARG_POS and not is_subtype(arg_type, allowed):
                ctx.api.msg.fail(
                    'Array constructor argument {} of type "{}"'
                    ' is not convertible to the array element type "{}"'
                    .format(arg_num, arg_type, et),
                    ctx.context)
            elif arg_kind == nodes.ARG_STAR:
                ty = ctx.api.named_generic_type("typing.Iterable", [allowed])
                if not is_subtype(arg_type, ty):
                    ctx.api.msg.fail(
                        'Array constructor argument {} of type "{}"'
                        ' is not convertible to the array element type "Iterable[{}]"'
                        .format(arg_num, arg_type, et),
                        ctx.context)

    return ctx.default_return_type
Пример #6
0
def join_instances(t: Instance, s: Instance, allow_interfaces: bool,
                   basic: BasicTypes) -> Type:
    """Calculate the join of two instance types.

    If allow_interfaces is True, also consider interface-type results for
    non-interface types.
    
    Return ErrorType if the result is ambiguous.
    """
    
    if t.type == s.type:
        # Simplest case: join two types with the same base type (but
        # potentially different arguments).
        if is_subtype(t, s):
            # Compatible; combine type arguments.
            args = [] # type: List[Type]
            for i in range(len(t.args)):
                args.append(join_types(t.args[i], s.args[i], basic))
            return Instance(t.type, args)
        else:
            # Incompatible; return trivial result object.
            return basic.object
    elif t.type.bases and is_subtype(t, s):
        return join_instances_via_supertype(t, s, allow_interfaces, basic)
    elif s.type.bases:
        return join_instances_via_supertype(s, t, allow_interfaces, basic)
    elif allow_interfaces:
        return join_instances_as_interface(t, s, basic)
    else:
        return basic.object
Пример #7
0
def meet_simple_away(s: Type, t: Type) -> Type:
    if isinstance(s, UnionType):
        return UnionType.make_simplified_union([x for x in s.items
                                                if not is_subtype(x, t)])
    elif not isinstance(s, AnyType) and is_subtype(s, t):
        return Void()
    else:
        return s
Пример #8
0
 def assert_simple_join(self, s: Type, t: Type, join: Type) -> None:
     result = join_types(s, t)
     actual = str(result)
     expected = str(join)
     assert_equal(actual, expected,
                  'join({}, {}) == {{}} ({{}} expected)'.format(s, t))
     assert_true(is_subtype(s, result),
                 '{} not subtype of {}'.format(s, result))
     assert_true(is_subtype(t, result),
                 '{} not subtype of {}'.format(t, result))
Пример #9
0
 def assert_simple_meet(self, s: Type, t: Type, meet: Type) -> None:
     result = meet_types(s, t)
     actual = str(result)
     expected = str(meet)
     assert_equal(actual, expected,
                  'meet({}, {}) == {{}} ({{}} expected)'.format(s, t))
     assert_true(is_subtype(result, s),
                 '{} not subtype of {}'.format(result, s))
     assert_true(is_subtype(result, t),
                 '{} not subtype of {}'.format(result, t))
Пример #10
0
 def assert_simple_meet(self, s, t, meet):
     result = meet_types(s, t)
     actual = str(result)
     expected = str(meet)
     assert_equal(actual, expected,
                  'meet({}, {}) == {{}} ({{}} expected)'.format(s, t))
     if not isinstance(s, ErrorType) and not isinstance(result, ErrorType):
         assert_true(is_subtype(result, s),
                     '{} not subtype of {}'.format(result, s))
     if not isinstance(t, ErrorType) and not isinstance(result, ErrorType):
         assert_true(is_subtype(result, t),
                     '{} not subtype of {}'.format(result, t))
Пример #11
0
 def assert_simple_join(self, s, t, join):
     result = join_types(s, t)
     actual = str(result)
     expected = str(join)
     assert_equal(actual, expected,
                  'join({}, {}) == {{}} ({{}} expected)'.format(s, t))
     if not isinstance(s, ErrorType) and not isinstance(result, ErrorType):
         assert_true(is_subtype(s, result),
                     '{} not subtype of {}'.format(s, result))
     if not isinstance(t, ErrorType) and not isinstance(result, ErrorType):
         assert_true(is_subtype(t, result),
                     '{} not subtype of {}'.format(t, result))
Пример #12
0
def check_method_type(functype: FunctionLike, itype: Instance, is_classmethod: bool,
                      context: Context, msg: MessageBuilder) -> None:
    for item in functype.items():
        if not item.arg_types or item.arg_kinds[0] not in (ARG_POS, ARG_STAR):
            # No positional first (self) argument (*args is okay).
            msg.invalid_method_type(item, context)
        elif not is_classmethod:
            # Check that self argument has type 'Any' or valid instance type.
            selfarg = item.arg_types[0]
            # If this is a method of a tuple class, correct for the fact that
            # we passed to typ.fallback in analyze_member_access. See #1432.
            if isinstance(selfarg, TupleType):
                selfarg = selfarg.fallback
            if not subtypes.is_subtype(selfarg, itype):
                msg.invalid_method_type(item, context)
        else:
            # Check that cls argument has type 'Any' or valid class type.
            # (This is sufficient for the current treatment of @classmethod,
            # but probably needs to be revisited when we implement Type[C]
            # or advanced variants of it like Type[<args>, C].)
            clsarg = item.arg_types[0]
            if isinstance(clsarg, CallableType) and clsarg.is_type_obj():
                if not subtypes.is_equivalent(clsarg.ret_type, itype):
                    msg.invalid_class_method_type(item, context)
            else:
                if not subtypes.is_equivalent(clsarg, AnyType()):
                    msg.invalid_class_method_type(item, context)
Пример #13
0
def solve_constraints(vars, constraints, basic):
    """Solve type constraints.

    Return lower bound for each type variable or None if the variable could
    not be solved.
    """
    # Collect a list of constraints for each type variable.
    cmap = {}
    for con in constraints:
        a = cmap.get(con.type_var, [])
        a.append(con)
        cmap[con.type_var] = a
    
    res = []

    # Solve each type variable separately.
    for tvar in vars:
        bottom = None
        top = None
        
        # Process each contraint separely, and calculate the lower and upper
        # bounds based on constraints. Note that we assume that the contraint
        # targets do not have contraint 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 top is None:
            if isinstance(bottom, Void):
                top = Void()
            else:
                top = basic.object
        
        if bottom is None:
            if isinstance(top, Void):
                bottom = Void()
            else:
                bottom = NoneTyp()
        
        if isinstance(top, Any) or isinstance(bottom, Any):
            top = Any()
            bottom = Any()
        
        # Pick the most specific type if it satisfies the constraints.
        if (not top or not bottom or is_subtype(bottom, top)) and (
                not isinstance(top, ErrorType) and
                not isinstance(bottom, ErrorType)):
            res.append(bottom)
        else:
            res.append(None)
    
    return res
Пример #14
0
def _infer_type_from_left_and_inferred_right(
    api: SemanticAnalyzerPluginInterface,
    node: Var,
    left_hand_explicit_type: Optional[types.Type],
    python_type_for_type: Union[Instance, UnionType],
) -> Optional[Union[Instance, UnionType]]:
    """Validate type when a left hand annotation is present and we also
    could infer the right hand side::

        attrname: SomeType = Column(SomeDBType)

    """
    if not is_subtype(left_hand_explicit_type, python_type_for_type):
        descriptor = api.lookup("__sa_Mapped", node)

        effective_type = Instance(descriptor.node, [python_type_for_type])

        msg = ("Left hand assignment '{}: {}' not compatible "
               "with ORM mapped expression of type {}")
        util.fail(
            api,
            msg.format(
                node.name,
                format_type(left_hand_explicit_type),
                format_type(effective_type),
            ),
            node,
        )

    return left_hand_explicit_type
Пример #15
0
 def visit_instance(self, t):
     if isinstance(self.s, Instance):
         return join_instances(t, self.s, True, self.basic)
     elif t.type == self.basic.std_type.type and is_subtype(self.s, t):
         return t
     else:
         return self.default(self.s)
Пример #16
0
def typed_dict_setdefault_callback(ctx: MethodContext) -> Type:
    """Type check TypedDict.setdefault and infer a precise return type."""
    if (isinstance(ctx.type, TypedDictType) and len(ctx.arg_types) == 2
            and len(ctx.arg_types[0]) == 1 and len(ctx.arg_types[1]) == 1):
        keys = try_getting_str_literals(ctx.args[0][0], ctx.arg_types[0][0])
        if keys is None:
            ctx.api.fail(message_registry.TYPEDDICT_KEY_MUST_BE_STRING_LITERAL,
                         ctx.context)
            return AnyType(TypeOfAny.from_error)

        default_type = ctx.arg_types[1][0]

        value_types = []
        for key in keys:
            value_type = ctx.type.items.get(key)

            if value_type is None:
                ctx.api.msg.typeddict_key_not_found(ctx.type, key, ctx.context)
                return AnyType(TypeOfAny.from_error)

            # The signature_callback above can't always infer the right signature
            # (e.g. when the expression is a variable that happens to be a Literal str)
            # so we need to handle the check ourselves here and make sure the provided
            # default can be assigned to all key-value pairs we're updating.
            if not is_subtype(default_type, value_type):
                ctx.api.msg.typeddict_setdefault_arguments_inconsistent(
                    default_type, value_type, ctx.context)
                return AnyType(TypeOfAny.from_error)

            value_types.append(value_type)

        return make_simplified_union(value_types)
    return ctx.default_return_type
Пример #17
0
def check_method_type(functype: FunctionLike, itype: Instance, is_classmethod: bool,
                      context: Context, msg: MessageBuilder) -> None:
    for item in functype.items():
        if not item.arg_types or item.arg_kinds[0] not in (ARG_POS, ARG_STAR):
            # No positional first (self) argument (*args is okay).
            msg.invalid_method_type(item, context)
        elif not is_classmethod:
            # Check that self argument has type 'Any' or valid instance type.
            selfarg = item.arg_types[0]
            # If this is a method of a tuple class, correct for the fact that
            # we passed to typ.fallback in analyze_member_access. See #1432.
            if isinstance(selfarg, TupleType):
                selfarg = selfarg.fallback
            if not subtypes.is_subtype(selfarg, itype):
                msg.invalid_method_type(item, context)
        else:
            # Check that cls argument has type 'Any' or valid class type.
            # (This is sufficient for the current treatment of @classmethod,
            # but probably needs to be revisited when we implement Type[C]
            # or advanced variants of it like Type[<args>, C].)
            clsarg = item.arg_types[0]
            if isinstance(clsarg, CallableType) and clsarg.is_type_obj():
                if not subtypes.is_equivalent(clsarg.ret_type, itype):
                    msg.invalid_class_method_type(item, context)
            else:
                if not subtypes.is_equivalent(clsarg, AnyType()):
                    msg.invalid_class_method_type(item, context)
Пример #18
0
    def assign_type(self, expr: Expression, type: Type, declared_type: Type, restrict_any: bool = False) -> None:
        if not expr.literal:
            return
        self.invalidate_dependencies(expr)

        if declared_type is None:
            # Not sure why this happens.  It seems to mainly happen in
            # member initialization.
            return
        if not is_subtype(type, declared_type):
            # Pretty sure this is only happens when there's a type error.

            # Ideally this function wouldn't be called if the
            # expression has a type error, though -- do other kinds of
            # errors cause this function to get called at invalid
            # times?
            return

        # If x is Any and y is int, after x = y we do not infer that x is int.
        # This could be changed.

        if isinstance(self.most_recent_enclosing_type(expr, type), AnyType) and not restrict_any:
            pass
        elif isinstance(type, AnyType):
            self.push(expr, declared_type)
        else:
            self.push(expr, type)

        for i in self.try_frames:
            # XXX This should probably not copy the entire frame, but
            # just copy this variable into a single stored frame.
            self.allow_jump(i)
Пример #19
0
 def visit_instance(self, t: Instance) -> None:
     # Type argument counts were checked in the main semantic analyzer pass. We assume
     # that the counts are correct here.
     info = t.type
     for (i, arg), tvar in zip(enumerate(t.args), info.defn.type_vars):
         if tvar.values:
             if isinstance(arg, TypeVarType):
                 arg_values = arg.values
                 if not arg_values:
                     self.fail('Type variable "{}" not valid as type '
                               'argument value for "{}"'.format(
                                   arg.name, info.name),
                               t,
                               code=codes.TYPE_VAR)
                     continue
             else:
                 arg_values = [arg]
             self.check_type_var_values(info, arg_values, tvar.name,
                                        tvar.values, i + 1, t)
         if not is_subtype(arg, tvar.upper_bound):
             self.fail('Type argument "{}" of "{}" must be '
                       'a subtype of "{}"'.format(arg, info.name,
                                                  tvar.upper_bound),
                       t,
                       code=codes.TYPE_VAR)
     super().visit_instance(t)
Пример #20
0
def check_self_arg(functype: FunctionLike, dispatched_arg_type: Type,
                   is_classmethod: bool, context: Context, name: str,
                   msg: MessageBuilder) -> None:
    """For x.f where A.f: A1 -> T, check that meet(type(x), A) <: A1 for each overload.

    dispatched_arg_type is meet(B, A) in the following example

        def g(x: B): x.f
        class A:
            f: Callable[[A1], None]
    """
    # TODO: this is too strict. We can return filtered overloads for matching definitions
    for item in functype.items():
        if not item.arg_types or item.arg_kinds[0] not in (ARG_POS, ARG_STAR):
            # No positional first (self) argument (*args is okay).
            msg.no_formal_self(name, item, context)
        else:
            selfarg = item.arg_types[0]
            if is_classmethod:
                dispatched_arg_type = TypeType.make_normalized(
                    dispatched_arg_type)
            if not subtypes.is_subtype(dispatched_arg_type,
                                       erase_to_bound(selfarg)):
                msg.incompatible_self_argument(name, dispatched_arg_type, item,
                                               is_classmethod, context)
Пример #21
0
    def make_simplified_union(items: List[Type], line: int = -1) -> Type:
        while any(isinstance(typ, UnionType) for typ in items):
            all_items = []  # type: List[Type]
            for typ in items:
                if isinstance(typ, UnionType):
                    all_items.extend(typ.items)
                else:
                    all_items.append(typ)
            items = all_items

        if any(isinstance(typ, AnyType) for typ in items):
            return AnyType()

        from mypy.subtypes import is_subtype
        removed = set()  # type: Set[int]
        for i in range(len(items)):
            if any(
                    is_subtype(items[i], items[j]) for j in range(len(items))
                    if j not in removed and j != i):
                removed.add(i)

        simplified_set = [
            items[i] for i in range(len(items)) if i not in removed
        ]
        return UnionType.make_union(simplified_set)
Пример #22
0
 def perform_special_format_checks(self, spec: ConversionSpecifier,
                                   call: CallExpr, repl: Expression,
                                   actual_type: Type,
                                   expected_type: Type) -> None:
     # TODO: try refactoring to combine this logic with % formatting.
     if spec.type == 'c':
         if isinstance(repl, (StrExpr, BytesExpr)) and len(repl.value) != 1:
             self.msg.requires_int_or_char(call, format_call=True)
         c_typ = get_proper_type(self.chk.type_map[repl])
         if isinstance(c_typ, Instance) and c_typ.last_known_value:
             c_typ = c_typ.last_known_value
         if isinstance(c_typ, LiteralType) and isinstance(c_typ.value, str):
             if len(c_typ.value) != 1:
                 self.msg.requires_int_or_char(call, format_call=True)
     if (not spec.type or spec.type == 's') and not spec.conversion:
         if self.chk.options.python_version >= (3, 0):
             if has_type_component(actual_type, 'builtins.bytes'):
                 self.msg.fail(
                     "On Python 3 '{}'.format(b'abc') produces \"b'abc'\";"
                     " use !r if this is a desired behavior",
                     call,
                     code=codes.STR_BYTES_PY3)
     if spec.flags:
         numeric_types = UnionType([
             self.named_type('builtins.int'),
             self.named_type('builtins.float')
         ])
         if (spec.type and spec.type not in NUMERIC_TYPES_NEW
                 or not spec.type
                 and not is_subtype(actual_type, numeric_types)
                 and not custom_special_method(actual_type, '__format__')):
             self.msg.fail(
                 'Numeric flags are only allowed for numeric types',
                 call,
                 code=codes.STRING_FORMATTING)
Пример #23
0
 def visit_literal_type(self, t: LiteralType) -> Type:
     if isinstance(self.s, LiteralType) and self.s == t:
         return t
     elif isinstance(self.s, Instance) and is_subtype(t.fallback, self.s):
         return t
     else:
         return self.default(self.s)
Пример #24
0
def register_function(ctx: PluginContext, singledispatch_obj: Instance, func: Type,
                      register_arg: Optional[Type] = None) -> None:
    """Register a function"""

    func = get_proper_type(func)
    if not isinstance(func, CallableType):
        return
    metadata = get_singledispatch_info(singledispatch_obj)
    if metadata is None:
        # if we never added the fallback to the type variables, we already reported an error, so
        # just don't do anything here
        return
    dispatch_type = get_dispatch_type(func, register_arg)
    if dispatch_type is None:
        # TODO: report an error here that singledispatch requires at least one argument
        # (might want to do the error reporting in get_dispatch_type)
        return
    fallback = metadata.fallback

    fallback_dispatch_type = fallback.arg_types[0]
    if not is_subtype(dispatch_type, fallback_dispatch_type):

        fail(ctx, 'Dispatch type {} must be subtype of fallback function first argument {}'.format(
                format_type(dispatch_type), format_type(fallback_dispatch_type)
            ), func.definition)
        return
    return
Пример #25
0
    def visit_mapping_pattern(self, o: MappingPattern) -> PatternType:
        current_type = get_proper_type(self.type_context[-1])
        can_match = True
        captures: Dict[Expression, Type] = {}
        for key, value in zip(o.keys, o.values):
            inner_type = self.get_mapping_item_type(o, current_type, key)
            if inner_type is None:
                can_match = False
                inner_type = self.chk.named_type("builtins.object")
            pattern_type = self.accept(value, inner_type)
            if is_uninhabited(pattern_type.type):
                can_match = False
            else:
                self.update_type_map(captures, pattern_type.captures)

        if o.rest is not None:
            mapping = self.chk.named_type("typing.Mapping")
            if is_subtype(current_type, mapping) and isinstance(current_type, Instance):
                mapping_inst = map_instance_to_supertype(current_type, mapping.type)
                dict_typeinfo = self.chk.lookup_typeinfo("builtins.dict")
                dict_type = fill_typevars(dict_typeinfo)
                rest_type = expand_type_by_instance(dict_type, mapping_inst)
            else:
                object_type = self.chk.named_type("builtins.object")
                rest_type = self.chk.named_generic_type("builtins.dict",
                                                        [object_type, object_type])

            captures[o.rest] = rest_type

        if can_match:
            # We can't narrow the type here, as Mapping key is invariant.
            new_type = self.type_context[-1]
        else:
            new_type = UninhabitedType()
        return PatternType(new_type, current_type, captures)
Пример #26
0
    def construct_sequence_child(self, outer_type: Type, inner_type: Type) -> Type:
        """
        If outer_type is a child class of typing.Sequence returns a new instance of
        outer_type, that is a Sequence of inner_type. If outer_type is not a child class of
        typing.Sequence just returns a Sequence of inner_type

        For example:
        construct_sequence_child(List[int], str) = List[str]
        """
        proper_type = get_proper_type(outer_type)
        if isinstance(proper_type, UnionType):
            types = [
                self.construct_sequence_child(item, inner_type) for item in proper_type.items
                if self.can_match_sequence(get_proper_type(item))
            ]
            return make_simplified_union(types)
        sequence = self.chk.named_generic_type("typing.Sequence", [inner_type])
        if is_subtype(outer_type, self.chk.named_type("typing.Sequence")):
            proper_type = get_proper_type(outer_type)
            assert isinstance(proper_type, Instance)
            empty_type = fill_typevars(proper_type.type)
            partial_type = expand_type_by_instance(empty_type, sequence)
            return expand_type_by_instance(partial_type, proper_type)
        else:
            return sequence
Пример #27
0
    def make_simplified_union(items: List[Type], line: int = -1) -> Type:
        while any(isinstance(typ, UnionType) for typ in items):
            all_items = []  # type: List[Type]
            for typ in items:
                if isinstance(typ, UnionType):
                    all_items.extend(typ.items)
                else:
                    all_items.append(typ)
            items = all_items

        if any(isinstance(typ, AnyType) for typ in items):
            return AnyType()

        from mypy.subtypes import is_subtype
        removed = set()  # type: Set[int]
        for i, ti in enumerate(items):
            if i in removed: continue
            # Keep track of the truishness info for deleted subtypes which can be relevant
            cbt = cbf = False
            for j, tj in enumerate(items):
                if i != j and is_subtype(tj, ti):
                    removed.add(j)
                    cbt = cbt or tj.can_be_true
                    cbf = cbf or tj.can_be_false
            # if deleted subtypes had more general truthiness, use that
            if not ti.can_be_true and cbt:
                items[i] = true_or_false(ti)
            elif not ti.can_be_false and cbf:
                items[i] = true_or_false(ti)

        simplified_set = [items[i] for i in range(len(items)) if i not in removed]
        return UnionType.make_union(simplified_set)
Пример #28
0
 def visit_literal_type(self, t: LiteralType) -> Type:
     if isinstance(self.s, LiteralType):
         return LiteralType(self.join(self.s.base, t.base), line=t.line)
     elif is_subtype(self.s, t.base):
         return t.base
     else:
         return self.join(self.s, t.base)
Пример #29
0
def class_callable(init_type: CallableType,
                   info: TypeInfo,
                   type_type: Instance,
                   special_sig: Optional[str],
                   is_new: bool,
                   orig_self_type: Optional[Type] = None) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    variables.extend(info.defn.type_vars)
    variables.extend(init_type.variables)

    from mypy.subtypes import is_subtype

    init_ret_type = get_proper_type(init_type.ret_type)
    orig_self_type = get_proper_type(orig_self_type)
    default_ret_type = fill_typevars(info)
    explicit_type = init_ret_type if is_new else orig_self_type
    if (isinstance(explicit_type, (Instance, TupleType))
            # Only use the declared return type from __new__ or declared self in __init__
            # if it is actually returning a subtype of what we would return otherwise.
            and is_subtype(
                explicit_type, default_ret_type, ignore_type_params=True)):
        ret_type = explicit_type  # type: Type
    else:
        ret_type = default_ret_type

    callable_type = init_type.copy_modified(ret_type=ret_type,
                                            fallback=type_type,
                                            name=None,
                                            variables=variables,
                                            special_sig=special_sig)
    c = callable_type.with_name(info.name)
    return c
Пример #30
0
 def visit_instance(self, t: Instance) -> Type:
     if isinstance(self.s, Instance):
         return join_instances(t, cast(Instance, self.s), self.basic)
     elif t.type == self.basic.type_type.type and is_subtype(self.s, t):
         return t
     else:
         return self.default(self.s)
Пример #31
0
def check_self_arg(functype: FunctionLike,
                   dispatched_arg_type: Type,
                   is_classmethod: bool,
                   context: Context, name: str,
                   msg: MessageBuilder) -> None:
    """For x.f where A.f: A1 -> T, check that meet(type(x), A) <: A1 for each overload.

    dispatched_arg_type is meet(B, A) in the following example

        def g(x: B): x.f
        class A:
            f: Callable[[A1], None]
    """
    # TODO: this is too strict. We can return filtered overloads for matching definitions
    for item in functype.items():
        if not item.arg_types or item.arg_kinds[0] not in (ARG_POS, ARG_STAR):
            # No positional first (self) argument (*args is okay).
            msg.no_formal_self(name, item, context)
        else:
            selfarg = item.arg_types[0]
            if is_classmethod:
                dispatched_arg_type = TypeType.make_normalized(dispatched_arg_type)
            if not subtypes.is_subtype(dispatched_arg_type, erase_to_bound(selfarg)):
                msg.incompatible_self_argument(name, dispatched_arg_type, item,
                                               is_classmethod, context)
Пример #32
0
 def visit_instance(self, t: Instance) -> Type:
     if isinstance(self.s, Instance):
         return join_instances(t, cast(Instance, self.s))
     elif t.type.fullname() == 'builtins.type' and is_subtype(self.s, t):
         return t
     else:
         return self.default(self.s)
Пример #33
0
 def visit_instance(self, t: Instance) -> None:
     # Type argument counts were checked in the main semantic analyzer pass. We assume
     # that the counts are correct here.
     info = t.type
     if isinstance(info, FakeInfo):
         return  # https://github.com/python/mypy/issues/11079
     for (i, arg), tvar in zip(enumerate(t.args), info.defn.type_vars):
         if isinstance(tvar, TypeVarType):
             if isinstance(arg, ParamSpecType):
                 # TODO: Better message
                 self.fail(f'Invalid location for ParamSpec "{arg.name}"',
                           t)
                 continue
             if tvar.values:
                 if isinstance(arg, TypeVarType):
                     arg_values = arg.values
                     if not arg_values:
                         self.fail(message_registry.
                                   INVALID_TYPEVAR_AS_TYPEARG.format(
                                       arg.name, info.name),
                                   t,
                                   code=codes.TYPE_VAR)
                         continue
                 else:
                     arg_values = [arg]
                 self.check_type_var_values(info, arg_values, tvar.name,
                                            tvar.values, i + 1, t)
             if not is_subtype(arg, tvar.upper_bound):
                 self.fail(
                     message_registry.INVALID_TYPEVAR_ARG_BOUND.format(
                         format_type(arg), info.name,
                         format_type(tvar.upper_bound)),
                     t,
                     code=codes.TYPE_VAR)
     super().visit_instance(t)
Пример #34
0
 def visit_literal_type(self, t: LiteralType) -> Type:
     if isinstance(self.s, LiteralType) and self.s == t:
         return t
     elif isinstance(self.s, Instance) and is_subtype(t.fallback, self.s):
         return t
     else:
         return self.default(self.s)
Пример #35
0
 def check_exception_type(self, info, context):
     t = Instance(info, [])
     if is_subtype(t, self.named_type('builtins.BaseException')):
         return t
     else:
         self.fail(messages.INVALID_EXCEPTION_TYPE, context)
         return Any()
Пример #36
0
 def visit_instance(self, t: Instance) -> ProperType:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 # N.B: We use zip instead of indexing because the lengths might have
                 # mismatches during daemon reprocessing.
                 for ta, sia in zip(t.args, si.args):
                     args.append(self.meet(ta, sia))
                 return Instance(t.type, args)
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
     elif isinstance(self.s, FunctionLike) and t.type.is_protocol:
         call = unpack_callback_protocol(t)
         if call:
             return meet_types(call, self.s)
     elif isinstance(self.s, FunctionLike) and self.s.is_type_obj(
     ) and t.type.is_metaclass():
         if is_subtype(self.s.fallback, t):
             return self.s
         return self.default(self.s)
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TupleType):
         return meet_types(t, self.s)
     elif isinstance(self.s, LiteralType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TypedDictType):
         return meet_types(t, self.s)
     return self.default(self.s)
Пример #37
0
def solve_constraints(vars: List[TypeVarId], constraints: List[Constraint],
                      strict: bool =True) -> 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, if strict=True then arbitrarily
    pick NoneTyp as the value of the type variable.  If strict=False,
    pick AnyType.
    """
    # Collect a list of constraints for each type variable.
    cmap = defaultdict(list)  # type: Dict[TypeVarId, List[Constraint]]
    for con in constraints:
        cmap[con.type_var].append(con)

    res = []  # type: List[Type]

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

        # Process each constraint separately, 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)
            else:
                if top is None:
                    top = c.target
                else:
                    top = meet_types(top, c.target)

        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 -- 'UninhabitedType' is the most specific type.
                if strict:
                    candidate = UninhabitedType()
                else:
                    candidate = AnyType()
        elif top is None:
            candidate = bottom
        elif is_subtype(bottom, top):
            candidate = bottom
        else:
            candidate = None
        res.append(candidate)

    return res
Пример #38
0
def join_instances_via_supertype(t: Instance, s: Instance) -> Type:
    # Give preference to joins via duck typing relationship, so that
    # join(int, float) == float, for example.
    if t.type._promote and is_subtype(t.type._promote, s):
        return join_types(t.type._promote, s)
    elif s.type._promote and is_subtype(s.type._promote, t):
        return join_types(t, s.type._promote)
    res = s
    mapped = map_instance_to_supertype(t, t.type.bases[0].type)
    join = join_instances(mapped, res)
    # If the join failed, fail. This is a defensive measure (this might
    # never happen).
    if isinstance(join, ErrorType):
        return join
    # Now the result must be an Instance, so the cast below cannot fail.
    res = cast(Instance, join)
    return res
Пример #39
0
 def most_recent_enclosing_type(self, expr: Node, type: Type) -> Type:
     if isinstance(type, AnyType):
         return self.get_declaration(expr)
     key = expr.literal_hash
     enclosers = ([self.get_declaration(expr)] +
                  [f[key] for f in self.frames
                   if key in f and is_subtype(type, f[key])])
     return enclosers[-1]
Пример #40
0
 def check_subtype(self, subtype, supertype, context, msg=messages.INCOMPATIBLE_TYPES):
     """Generate an error if the subtype is not compatible with
     supertype."""
     if not is_subtype(subtype, supertype):
         if isinstance(subtype, Void):
             self.msg.does_not_return_value(subtype, context)
         else:
             self.fail(msg, context)
Пример #41
0
def join_instances_via_supertype(t: Instance, s: Instance) -> Type:
    # Give preference to joins via duck typing relationship, so that
    # join(int, float) == float, for example.
    if t.type._promote and is_subtype(t.type._promote, s):
        return join_types(t.type._promote, s)
    elif s.type._promote and is_subtype(s.type._promote, t):
        return join_types(t, s.type._promote)
    res = s
    mapped = map_instance_to_supertype(t, t.type.bases[0].type)
    join = join_instances(mapped, res)
    # If the join failed, fail. This is a defensive measure (this might
    # never happen).
    if isinstance(join, ErrorType):
        return join
    # Now the result must be an Instance, so the cast below cannot fail.
    res = cast(Instance, join)
    return res
Пример #42
0
 def most_recent_enclosing_type(self, expr: Expression, type: Type) -> Type:
     if isinstance(type, AnyType):
         return self.get_declaration(expr)
     key = expr.literal_hash
     enclosers = [self.get_declaration(expr)] + [
         f[key] for f in self.frames if key in f and is_subtype(type, f[key])
     ]
     return enclosers[-1]
Пример #43
0
 def should_self_match(self, typ: Type) -> bool:
     typ = get_proper_type(typ)
     if isinstance(typ, Instance) and typ.type.is_named_tuple:
         return False
     for other in self.self_match_types:
         if is_subtype(typ, other):
             return True
     return False
Пример #44
0
    def check_simple_str_interpolation(self,
                                       specifiers: List[ConversionSpecifier],
                                       replacements: Expression,
                                       expr: FormatStringExpr) -> None:
        """Check % string interpolation with positional specifiers '%s, %d' % ('yes, 42')."""
        checkers = self.build_replacement_checkers(specifiers, replacements,
                                                   expr)
        if checkers is None:
            return

        rhs_type = get_proper_type(self.accept(replacements))
        rep_types: List[Type] = []
        if isinstance(rhs_type, TupleType):
            rep_types = rhs_type.items
        elif isinstance(rhs_type, AnyType):
            return
        elif isinstance(
                rhs_type,
                Instance) and rhs_type.type.fullname == 'builtins.tuple':
            # Assume that an arbitrary-length tuple has the right number of items.
            rep_types = [rhs_type.args[0]] * len(checkers)
        elif isinstance(rhs_type, UnionType):
            for typ in rhs_type.relevant_items():
                temp_node = TempNode(typ)
                temp_node.line = replacements.line
                self.check_simple_str_interpolation(specifiers, temp_node,
                                                    expr)
            return
        else:
            rep_types = [rhs_type]

        if len(checkers) > len(rep_types):
            # Only check the fix-length Tuple type. Other Iterable types would skip.
            if (is_subtype(rhs_type, self.chk.named_type("typing.Iterable"))
                    and not isinstance(rhs_type, TupleType)):
                return
            else:
                self.msg.too_few_string_formatting_arguments(replacements)
        elif len(checkers) < len(rep_types):
            self.msg.too_many_string_formatting_arguments(replacements)
        else:
            if len(checkers) == 1:
                check_node, check_type = checkers[0]
                if isinstance(rhs_type, TupleType) and len(
                        rhs_type.items) == 1:
                    check_type(rhs_type.items[0])
                else:
                    check_node(replacements)
            elif (isinstance(replacements, TupleExpr) and not any(
                    isinstance(item, StarExpr)
                    for item in replacements.items)):
                for checks, rep_node in zip(checkers, replacements.items):
                    check_node, check_type = checks
                    check_node(rep_node)
            else:
                for checks, rep_type in zip(checkers, rep_types):
                    check_node, check_type = checks
                    check_type(rep_type)
Пример #45
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
Пример #46
0
 def visit_instance(self, t: Instance) -> ProperType:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 for i in range(len(t.args)):
                     args.append(self.meet(t.args[i], si.args[i]))
                 return Instance(t.type, args)
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
     elif isinstance(self.s, FunctionLike) and t.type.is_protocol:
         call = unpack_callback_protocol(t)
         if call:
             return meet_types(call, self.s)
     elif isinstance(self.s, FunctionLike) and self.s.is_type_obj(
     ) and t.type.is_metaclass():
         if is_subtype(self.s.fallback, t):
             return self.s
         return self.default(self.s)
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TupleType):
         return meet_types(t, self.s)
     elif isinstance(self.s, LiteralType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TypedDictType):
         return meet_types(t, self.s)
     return self.default(self.s)
Пример #47
0
def join_instances_via_supertype(t: Instance, s: Instance) -> Type:
    # Give preference to joins via duck typing relationship, so that
    # join(int, float) == float, for example.
    if t.type._promote and is_subtype(t.type._promote, s):
        return join_types(t.type._promote, s)
    elif s.type._promote and is_subtype(s.type._promote, t):
        return join_types(t, s.type._promote)
    # Compute the "best" supertype of t when joined with s.
    # The definition of "best" may evolve; for now it is the one with
    # the longest MRO.  Ties are broken by using the earlier base.
    best = None  # type: Optional[Type]
    for base in t.type.bases:
        mapped = map_instance_to_supertype(t, base.type)
        res = join_instances(mapped, s)
        if best is None or is_better(res, best):
            best = res
    assert best is not None
    return best
Пример #48
0
def is_ndarray_of_bools(typ: Type):
    if not isinstance(typ, Instance):
        return False
    return is_subtype(
        typ,
        API.named_generic_type(
            'numpy.ndarray',
            args=[bool_type(), API.named_type('numpy._Dimension')])) and (
                not is_same_type(typ.args[1], AnyType(TypeOfAny.unannotated)))
Пример #49
0
def join_instances_via_supertype(t: Instance, s: Instance) -> Type:
    # Give preference to joins via duck typing relationship, so that
    # join(int, float) == float, for example.
    if t.type._promote and is_subtype(t.type._promote, s):
        return join_types(t.type._promote, s)
    elif s.type._promote and is_subtype(s.type._promote, t):
        return join_types(t, s.type._promote)
    # Compute the "best" supertype of t when joined with s.
    # The definition of "best" may evolve; for now it is the one with
    # the longest MRO.  Ties are broken by using the earlier base.
    best = None  # type: Type
    for base in t.type.bases:
        mapped = map_instance_to_supertype(t, base.type)
        res = join_instances(mapped, s)
        if best is None or is_better(res, best):
            best = res
    assert best is not None
    return best
Пример #50
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     # TODO: Implement a better algorithm that covers at least the same cases
     # as TypeJoinVisitor.visit_overloaded().
     s = self.s
     if isinstance(s, FunctionLike):
         if s.items() == t.items():
             return Overloaded(t.items())
         elif is_subtype(s, t):
             return s
         elif is_subtype(t, s):
             return t
         else:
             return meet_types(t.fallback, s.fallback)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return meet_types(t.fallback, s)
Пример #51
0
 def visit_instance(self, t: Instance) -> None:
     info = t.type
     # Check type argument count.
     if len(t.args) != len(info.type_vars):
         if len(t.args) == 0:
             from_builtins = t.type.fullname() in nongen_builtins and not t.from_generic_builtin
             if ('generics' in self.options.disallow_any and
                     not self.is_typeshed_stub and
                     from_builtins):
                 alternative = nongen_builtins[t.type.fullname()]
                 self.fail(messages.IMPLICIT_GENERIC_ANY_BUILTIN.format(alternative), t)
             # Insert implicit 'Any' type arguments.
             any_type = AnyType(from_omitted_generics=not from_builtins, line=t.line,
                                column=t.line)
             t.args = [any_type] * len(info.type_vars)
             return
         # Invalid number of type parameters.
         n = len(info.type_vars)
         s = '{} type arguments'.format(n)
         if n == 0:
             s = 'no type arguments'
         elif n == 1:
             s = '1 type argument'
         act = str(len(t.args))
         if act == '0':
             act = 'none'
         self.fail('"{}" expects {}, but {} given'.format(
             info.name(), s, act), t)
         # Construct the correct number of type arguments, as
         # otherwise the type checker may crash as it expects
         # things to be right.
         t.args = [AnyType() for _ in info.type_vars]
         t.invalid = True
     elif info.defn.type_vars:
         # Check type argument values.
         for (i, arg), tvar in zip(enumerate(t.args), info.defn.type_vars):
             if tvar.values:
                 if isinstance(arg, TypeVarType):
                     arg_values = arg.values
                     if not arg_values:
                         self.fail('Type variable "{}" not valid as type '
                                   'argument value for "{}"'.format(
                                       arg.name, info.name()), t)
                         continue
                 else:
                     arg_values = [arg]
                 self.check_type_var_values(info, arg_values,
                                            tvar.values, i + 1, t)
             if not is_subtype(arg, tvar.upper_bound):
                 self.fail('Type argument "{}" of "{}" must be '
                           'a subtype of "{}"'.format(
                               arg, info.name(), tvar.upper_bound), t)
     for arg in t.args:
         arg.accept(self)
     if info.is_newtype:
         for base in info.bases:
             base.accept(self)
Пример #52
0
 def most_recent_enclosing_type(self, expr: BindableExpression, type: Type) -> Optional[Type]:
     if isinstance(type, AnyType):
         return get_declaration(expr)
     key = literal_hash(expr)
     assert key is not None
     enclosers = ([get_declaration(expr)] +
                  [f[key] for f in self.frames
                   if key in f and is_subtype(type, f[key])])
     return enclosers[-1]
Пример #53
0
    def join_instances(self, t: Instance, s: Instance) -> ProperType:
        if (t, s) in self.seen_instances or (s, t) in self.seen_instances:
            return object_from_instance(t)

        self.seen_instances.append((t, s))
        """Calculate the join of two instance types."""
        if t.type == s.type:
            # Simplest case: join two types with the same base type (but
            # potentially different arguments).

            # Combine type arguments.
            args: List[Type] = []
            # N.B: We use zip instead of indexing because the lengths might have
            # mismatches during daemon reprocessing.
            for ta, sa, type_var in zip(t.args, s.args, t.type.defn.type_vars):
                ta_proper = get_proper_type(ta)
                sa_proper = get_proper_type(sa)
                new_type: Optional[Type] = None
                if isinstance(ta_proper, AnyType):
                    new_type = AnyType(TypeOfAny.from_another_any, ta_proper)
                elif isinstance(sa_proper, AnyType):
                    new_type = AnyType(TypeOfAny.from_another_any, sa_proper)
                elif type_var.variance == COVARIANT:
                    new_type = join_types(ta, sa, self)
                    if len(type_var.values
                           ) != 0 and new_type not in type_var.values:
                        self.seen_instances.pop()
                        return object_from_instance(t)
                    if not is_subtype(new_type, type_var.upper_bound):
                        self.seen_instances.pop()
                        return object_from_instance(t)
                elif type_var.variance == CONTRAVARIANT:
                    new_type = meet.meet_types(ta, sa)
                    if len(type_var.values
                           ) != 0 and new_type not in type_var.values:
                        self.seen_instances.pop()
                        return object_from_instance(t)
                    # No need to check subtype, as ta and sa already have to be subtypes of
                    # upper_bound
                elif type_var.variance == INVARIANT:
                    new_type = join_types(ta, sa)
                    if not is_equivalent(ta, sa):
                        self.seen_instances.pop()
                        return object_from_instance(t)
                assert new_type is not None
                args.append(new_type)
            result: ProperType = Instance(t.type, args)
        elif t.type.bases and is_subtype_ignoring_tvars(t, s):
            result = self.join_instances_via_supertype(t, s)
        else:
            # Now t is not a subtype of s, and t != s. Now s could be a subtype
            # of t; alternatively, we need to find a common supertype. This works
            # in of the both cases.
            result = self.join_instances_via_supertype(s, t)

        self.seen_instances.pop()
        return result
Пример #54
0
 def most_recent_enclosing_type(self, expr: BindableExpression, type: Type) -> Optional[Type]:
     if isinstance(type, AnyType):
         return get_declaration(expr)
     key = literal_hash(expr)
     assert key is not None
     enclosers = ([get_declaration(expr)] +
                  [f.types[key] for f in self.frames
                   if key in f.types and is_subtype(type, f.types[key])])
     return enclosers[-1]
Пример #55
0
 def visit_overloaded(self, t: Overloaded) -> ProperType:
     # TODO: Implement a better algorithm that covers at least the same cases
     # as TypeJoinVisitor.visit_overloaded().
     s = self.s
     if isinstance(s, FunctionLike):
         if s.items() == t.items():
             return Overloaded(t.items())
         elif is_subtype(s, t):
             return s
         elif is_subtype(t, s):
             return t
         else:
             return meet_types(t.fallback, s.fallback)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return meet_types(t.fallback, s)
Пример #56
0
def is_ndarray(typ: Type):
    if not isinstance(typ, Instance):
        return False
    return is_subtype(
        typ,
        API.named_generic_type('numpy.ndarray',
                               args=[
                                   AnyType(TypeOfAny.unannotated),
                                   AnyType(TypeOfAny.unannotated)
                               ]))
Пример #57
0
def join_simple(declaration: Type, s: Type, t: Type) -> Type:
    """Return a simple least upper bound given the declared type."""

    if (s.can_be_true, s.can_be_false) != (t.can_be_true, t.can_be_false):
        # if types are restricted in different ways, use the more general versions
        s = true_or_false(s)
        t = true_or_false(t)

    if isinstance(s, AnyType):
        return s

    if isinstance(s, ErasedType):
        return t

    if is_subtype(s, t):
        return t

    if is_subtype(t, s):
        return s

    if isinstance(declaration, UnionType):
        return UnionType.make_simplified_union([s, t])

    if isinstance(s, NoneTyp) and not isinstance(t, NoneTyp):
        s, t = t, s

    if isinstance(s, UninhabitedType) and not isinstance(t, UninhabitedType):
        s, t = t, s

    value = t.accept(TypeJoinVisitor(s))

    if value is None:
        # XXX this code path probably should be avoided.
        # It seems to happen when a line (x = y) is a type error, and
        # it's not clear that assuming that x is arbitrary afterward
        # is a good idea.
        return declaration

    if declaration is None or is_subtype(value, declaration):
        return value

    return declaration
Пример #58
0
def join_simple(declaration: Type, s: Type, t: Type) -> Type:
    """Return a simple least upper bound given the declared type."""

    if (s.can_be_true, s.can_be_false) != (t.can_be_true, t.can_be_false):
        # if types are restricted in different ways, use the more general versions
        s = true_or_false(s)
        t = true_or_false(t)

    if isinstance(s, AnyType):
        return s

    if isinstance(s, ErasedType):
        return t

    if is_subtype(s, t):
        return t

    if is_subtype(t, s):
        return s

    if isinstance(declaration, UnionType):
        return UnionType.make_simplified_union([s, t])

    if isinstance(s, NoneTyp) and not isinstance(t, NoneTyp):
        s, t = t, s

    if isinstance(s, UninhabitedType) and not isinstance(t, UninhabitedType):
        s, t = t, s

    value = t.accept(TypeJoinVisitor(s))

    if value is None:
        # XXX this code path probably should be avoided.
        # It seems to happen when a line (x = y) is a type error, and
        # it's not clear that assuming that x is arbitrary afterward
        # is a good idea.
        return declaration

    if declaration is None or is_subtype(value, declaration):
        return value

    return declaration
Пример #59
0
 def visit_callable_type(self, t: CallableType) -> Type:
     if isinstance(self.s, CallableType) and is_similar_callables(
             t, cast(CallableType, self.s)):
         return combine_similar_callables(t, cast(CallableType, self.s))
     elif t.is_type_obj() and is_subtype(self.s, t.fallback):
         return t.fallback
     elif (t.is_type_obj() and isinstance(self.s, Instance)
           and cast(Instance, self.s).type == t.fallback):
         return t.fallback
     else:
         return self.default(self.s)