예제 #1
0
파일: subtypes.py 프로젝트: alexandrul/mypy
 def visit_overloaded(self, left: Overloaded) -> bool:
     right = self.right
     if isinstance(right, Instance):
         return is_subtype(left.fallback, right)
     elif isinstance(right, CallableType) or is_named_instance(
             right, 'builtins.type'):
         for item in left.items():
             if is_subtype(item, right, self.check_type_parameter,
                           ignore_pos_arg_names=self.ignore_pos_arg_names):
                 return True
         return False
     elif isinstance(right, Overloaded):
         # TODO: this may be too restrictive
         if len(left.items()) != len(right.items()):
             return False
         for i in range(len(left.items())):
             if not is_subtype(left.items()[i], right.items()[i], self.check_type_parameter,
                               ignore_pos_arg_names=self.ignore_pos_arg_names):
                 return False
         return True
     elif isinstance(right, UnboundType):
         return True
     elif isinstance(right, TypeType):
         # All the items must have the same type object status, so
         # it's sufficient to query only (any) one of them.
         # This is unsound, we don't check the __init__ signature.
         return left.is_type_obj() and is_subtype(left.items()[0].ret_type, right.item)
     else:
         return False
예제 #2
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     items = []  # type: List[CallableType]
     for item in t.items():
         new_item = item.accept(self)
         assert isinstance(new_item, CallableType)
         items.append(new_item)
     return Overloaded(items)
예제 #3
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     items = []  # type: List[CallableType]
     for item in t.items():
         new = item.accept(self)
         if isinstance(new, CallableType):
             items.append(new)
         else:
             raise RuntimeError('CallableType expected, but got {}'.format(type(new)))
     return Overloaded(items=items)
예제 #4
0
파일: meet.py 프로젝트: chadrik/mypy
 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)
예제 #5
0
 def infer_against_overloaded(self, overloaded: Overloaded,
                              template: Callable) -> List[Constraint]:
     # Create constraints by matching an overloaded type against a template.
     # This is tricky to do in general. We cheat by only matching against
     # the first overload item, and by only matching the return type. This
     # seems to work somewhat well, but we should really use a more
     # reliable technique.
     item = overloaded.items()[0]
     return infer_constraints(template.ret_type, item.ret_type,
                              self.direction)
예제 #6
0
def find_matching_overload_item(overloaded: Overloaded, template: CallableType) -> CallableType:
    """Disambiguate overload item against a template."""
    items = overloaded.items()
    for item in items:
        # Return type may be indeterminate in the template, so ignore it when performing a
        # subtype check.
        if mypy.subtypes.is_callable_subtype(item, template, ignore_return=True):
            return item
    # Fall back to the first item if we can't find a match. This is totally arbitrary --
    # maybe we should just bail out at this point.
    return items[0]
예제 #7
0
파일: subtypes.py 프로젝트: nierob/mypy
 def visit_overloaded(self, left: Overloaded) -> bool:
     right = self.right
     if isinstance(right, Instance):
         return is_subtype(left.fallback, right)
     elif isinstance(right, CallableType) or is_named_instance(right, "builtins.type"):
         for item in left.items():
             if is_subtype(item, right, self.check_type_parameter):
                 return True
         return False
     elif isinstance(right, Overloaded):
         # TODO: this may be too restrictive
         if len(left.items()) != len(right.items()):
             return False
         for i in range(len(left.items())):
             if not is_subtype(left.items()[i], right.items()[i], self.check_type_parameter):
                 return False
         return True
     elif isinstance(right, UnboundType):
         return True
     else:
         return False
예제 #8
0
파일: join.py 프로젝트: chadrik/mypy
 def visit_overloaded(self, t: Overloaded) -> Type:
     # This is more complex than most other cases. Here are some
     # examples that illustrate how this works.
     #
     # First let's define a concise notation:
     #  - Cn are callable types (for n in 1, 2, ...)
     #  - Ov(C1, C2, ...) is an overloaded type with items C1, C2, ...
     #  - Callable[[T, ...], S] is written as [T, ...] -> S.
     #
     # We want some basic properties to hold (assume Cn are all
     # unrelated via Any-similarity):
     #
     #   join(Ov(C1, C2), C1) == C1
     #   join(Ov(C1, C2), Ov(C1, C2)) == Ov(C1, C2)
     #   join(Ov(C1, C2), Ov(C1, C3)) == C1
     #   join(Ov(C2, C2), C3) == join of fallback types
     #
     # The presence of Any types makes things more interesting. The join is the
     # most general type we can get with respect to Any:
     #
     #   join(Ov([int] -> int, [str] -> str), [Any] -> str) == Any -> str
     #
     # We could use a simplification step that removes redundancies, but that's not
     # implemented right now. Consider this example, where we get a redundancy:
     #
     #   join(Ov([int, Any] -> Any, [str, Any] -> Any), [Any, int] -> Any) ==
     #       Ov([Any, int] -> Any, [Any, int] -> Any)
     #
     # TODO: Consider more cases of callable subtyping.
     result = []  # type: List[CallableType]
     s = self.s
     if isinstance(s, FunctionLike):
         # The interesting case where both types are function types.
         for t_item in t.items():
             for s_item in s.items():
                 if is_similar_callables(t_item, s_item):
                     if is_equivalent(t_item, s_item):
                         result.append(combine_similar_callables(t_item, s_item))
                     elif is_subtype(t_item, s_item):
                         result.append(s_item)
         if result:
             # TODO: Simplify redundancies from the result.
             if len(result) == 1:
                 return result[0]
             else:
                 return Overloaded(result)
         return join_types(t.fallback, s.fallback)
     elif isinstance(s, Instance) and s.type.is_protocol:
         call = unpack_callback_protocol(s)
         if call:
             return join_types(t, call)
     return join_types(t.fallback, s)
예제 #9
0
 def visit_overloaded(self, left: Overloaded) -> bool:
     right = self.right
     if is_named_instance(right, 'builtins.object'):
         return True
     elif isinstance(right, Callable) or is_named_instance(
                                              right, 'builtins.type'):
         for item in left.items():
             if is_subtype(item, right):
                 return True
         return False
     elif isinstance(right, Overloaded):
         # TODO: this may be too restrictive
         if len(left.items()) != len(right.items()):
             return False
         for i in range(len(left.items())):
             if not is_subtype(left.items()[i], right.items()[i]):
                 return False
         return True
     elif isinstance(right, UnboundType):
         return True
     else:
         return False
예제 #10
0
파일: subtypes.py 프로젝트: sevajide/mypy
 def visit_overloaded(self, left: Overloaded) -> bool:
     right = self.right
     if isinstance(right, Instance):
         return is_subtype(left.fallback, right)
     elif isinstance(right, CallableType) or is_named_instance(
             right, 'builtins.type'):
         for item in left.items():
             if is_subtype(item, right, self.check_type_parameter):
                 return True
         return False
     elif isinstance(right, Overloaded):
         # TODO: this may be too restrictive
         if len(left.items()) != len(right.items()):
             return False
         for i in range(len(left.items())):
             if not is_subtype(left.items()[i],
                               right.items()[i], self.check_type_parameter):
                 return False
         return True
     elif isinstance(right, UnboundType):
         return True
     else:
         return False
예제 #11
0
def find_matching_overload_item(overloaded: Overloaded,
                                template: CallableType) -> CallableType:
    """Disambiguate overload item against a template."""
    items = overloaded.items()
    for item in items:
        # Return type may be indeterminate in the template, so ignore it when performing a
        # subtype check.
        if mypy.subtypes.is_callable_subtype(item,
                                             template,
                                             ignore_return=True):
            return item
    # Fall back to the first item if we can't find a match. This is totally arbitrary --
    # maybe we should just bail out at this point.
    return items[0]
예제 #12
0
파일: join.py 프로젝트: GigonicMan/mypy
 def visit_overloaded(self, t: Overloaded) -> Type:
     # This is more complex than most other cases. Here are some
     # examples that illustrate how this works.
     #
     # First let's define a concise notation:
     #  - Cn are callable types (for n in 1, 2, ...)
     #  - Ov(C1, C2, ...) is an overloaded type with items C1, C2, ...
     #  - Callable[[T, ...], S] is written as [T, ...] -> S.
     #
     # We want some basic properties to hold (assume Cn are all
     # unrelated via Any-similarity):
     #
     #   join(Ov(C1, C2), C1) == C1
     #   join(Ov(C1, C2), Ov(C1, C2)) == Ov(C1, C2)
     #   join(Ov(C1, C2), Ov(C1, C3)) == C1
     #   join(Ov(C2, C2), C3) == join of fallback types
     #
     # The presence of Any types makes things more interesting. The join is the
     # most general type we can get with respect to Any:
     #
     #   join(Ov([int] -> int, [str] -> str), [Any] -> str) == Any -> str
     #
     # We could use a simplification step that removes redundancies, but that's not
     # implemented right now. Consider this example, where we get a redundancy:
     #
     #   join(Ov([int, Any] -> Any, [str, Any] -> Any), [Any, int] -> Any) ==
     #       Ov([Any, int] -> Any, [Any, int] -> Any)
     #
     # TODO: Consider more cases of callable subtyping.
     result = []  # type: List[CallableType]
     s = self.s
     if isinstance(s, FunctionLike):
         # The interesting case where both types are function types.
         for t_item in t.items():
             for s_item in s.items():
                 if is_similar_callables(t_item, s_item):
                     if is_equivalent(t_item, s_item):
                         result.append(
                             combine_similar_callables(t_item, s_item))
                     elif is_subtype(t_item, s_item):
                         result.append(s_item)
         if result:
             # TODO: Simplify redundancies from the result.
             if len(result) == 1:
                 return result[0]
             else:
                 return Overloaded(result)
         return join_types(t.fallback, s.fallback)
     return join_types(t.fallback, s)
예제 #13
0
 def visit_overloaded(self, t: Overloaded) -> None:
     for item in t.items():
         item.accept(self)
예제 #14
0
 def visit_overloaded(self, typ: Overloaded) -> List[str]:
     triggers = []
     for item in typ.items():
         triggers.extend(get_type_triggers(item))
     return triggers
예제 #15
0
파일: expandtype.py 프로젝트: lamby/mypy
 def visit_overloaded(self, t: Overloaded) -> Type:
     items = []  # type: List[CallableType]
     for item in t.items():
         items.append(cast(CallableType, item.accept(self)))
     return Overloaded(items)
예제 #16
0
파일: typeanal.py 프로젝트: elarivie/mypy
 def visit_overloaded(self, t: Overloaded) -> None:
     for item in t.items():
         item.accept(self)
예제 #17
0
 def visit_overloaded(self, t: Overloaded) -> None:
     self.traverse_types(t.items())
예제 #18
0
파일: subtypes.py 프로젝트: sixolet/mypy
    def visit_overloaded(self, left: Overloaded) -> bool:
        right = self.right
        if isinstance(right, Instance):
            return is_subtype(left.fallback, right)
        elif isinstance(right, CallableType):
            for item in left.items():
                if is_subtype(item, right, self.check_type_parameter,
                              ignore_pos_arg_names=self.ignore_pos_arg_names):
                    return True
            return False
        elif isinstance(right, Overloaded):
            # Ensure each overload in the right side (the supertype) is accounted for.
            previous_match_left_index = -1
            matched_overloads = set()
            possible_invalid_overloads = set()

            for right_index, right_item in enumerate(right.items()):
                found_match = False

                for left_index, left_item in enumerate(left.items()):
                    subtype_match = is_subtype(left_item, right_item, self.check_type_parameter,
                                               ignore_pos_arg_names=self.ignore_pos_arg_names)

                    # Order matters: we need to make sure that the index of
                    # this item is at least the index of the previous one.
                    if subtype_match and previous_match_left_index <= left_index:
                        if not found_match:
                            # Update the index of the previous match.
                            previous_match_left_index = left_index
                            found_match = True
                            matched_overloads.add(left_item)
                            possible_invalid_overloads.discard(left_item)
                    else:
                        # If this one overlaps with the supertype in any way, but it wasn't
                        # an exact match, then it's a potential error.
                        if (is_callable_subtype(left_item, right_item, ignore_return=True,
                                            ignore_pos_arg_names=self.ignore_pos_arg_names) or
                                is_callable_subtype(right_item, left_item, ignore_return=True,
                                                ignore_pos_arg_names=self.ignore_pos_arg_names)):
                            # If this is an overload that's already been matched, there's no
                            # problem.
                            if left_item not in matched_overloads:
                                possible_invalid_overloads.add(left_item)

                if not found_match:
                    return False

            if possible_invalid_overloads:
                # There were potentially invalid overloads that were never matched to the
                # supertype.
                return False
            return True
        elif isinstance(right, UnboundType):
            return True
        elif isinstance(right, TypeType):
            # All the items must have the same type object status, so
            # it's sufficient to query only (any) one of them.
            # This is unsound, we don't check all the __init__ signatures.
            return left.is_type_obj() and is_subtype(left.items()[0], right)
        else:
            return False
예제 #19
0
파일: deps.py 프로젝트: sixolet/mypy
 def visit_overloaded(self, typ: Overloaded) -> List[str]:
     triggers = []
     for item in typ.items():
         triggers.extend(get_type_triggers(item))
     return triggers
예제 #20
0
 def visit_overloaded(self, typ: Overloaded) -> SnapshotItem:
     return ('Overloaded', snapshot_types(typ.items()))
예제 #21
0
 def visit_overloaded(self, template: Overloaded) -> List[Constraint]:
     res = []  # type: List[Constraint]
     for t in template.items():
         res.extend(infer_constraints(t, self.actual, self.direction))
     return res
예제 #22
0
파일: sametypes.py 프로젝트: rowillia/mypy
 def visit_overloaded(self, left: Overloaded) -> bool:
     if isinstance(self.right, Overloaded):
         return is_same_types(left.items(), self.right.items())
     else:
         return False
예제 #23
0
 def visit_overloaded(self, template: Overloaded) -> List[Constraint]:
     res = []  # type: List[Constraint]
     for t in template.items():
         res.extend(infer_constraints(t, self.actual, self.direction))
     return res
예제 #24
0
 def visit_overloaded(self, t: Overloaded) -> T:
     return self.query_types(t.items())
예제 #25
0
 def visit_overloaded(self, t: Overloaded) -> T:
     return self.query_types(t.items())
예제 #26
0
파일: indirection.py 프로젝트: chadrik/mypy
 def visit_overloaded(self, t: types.Overloaded) -> Set[str]:
     return self._visit(t.items()) | self._visit(t.fallback)
예제 #27
0
 def visit_overloaded(self, typ: Overloaded) -> SnapshotItem:
     return ('Overloaded', snapshot_types(typ.items()))
예제 #28
0
 def visit_overloaded(self, t: Overloaded) -> None:
     self.traverse_types(t.items())
예제 #29
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     items = [] # type: List[Callable]
     for item in t.items():
         items.append(cast(Callable, item.accept(self)))
     return Overloaded(items)
예제 #30
0
파일: astmerge.py 프로젝트: rheehot/mypy
 def visit_overloaded(self, t: Overloaded) -> None:
     for item in t.items():
         item.accept(self)
     # Fallback can be None for overloaded types that haven't been semantically analyzed.
     if t.fallback is not None:
         t.fallback.accept(self)
예제 #31
0
 def visit_overloaded(self, t: Overloaded) -> None:
     for ct in t.items():
         ct.accept(self)
예제 #32
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     return t.items()[0].accept(self)
예제 #33
0
 def visit_overloaded(self, left: Overloaded) -> bool:
     if isinstance(self.right, Overloaded):
         return is_same_types(left.items(), self.right.items())
     else:
         return False
예제 #34
0
파일: astmerge.py 프로젝트: python/mypy
 def visit_overloaded(self, t: Overloaded) -> None:
     for item in t.items():
         item.accept(self)
     # Fallback can be None for overloaded types that haven't been semantically analyzed.
     if t.fallback is not None:
         t.fallback.accept(self)
예제 #35
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     return t.items()[0].accept(self)
예제 #36
0
    def visit_overloaded(self, left: Overloaded) -> bool:
        right = self.right
        if isinstance(right, Instance):
            return is_subtype(left.fallback, right)
        elif isinstance(right, CallableType):
            for item in left.items():
                if is_subtype(item,
                              right,
                              self.check_type_parameter,
                              ignore_pos_arg_names=self.ignore_pos_arg_names):
                    return True
            return False
        elif isinstance(right, Overloaded):
            # Ensure each overload in the right side (the supertype) is accounted for.
            previous_match_left_index = -1
            matched_overloads = set()
            possible_invalid_overloads = set()

            for right_index, right_item in enumerate(right.items()):
                found_match = False

                for left_index, left_item in enumerate(left.items()):
                    subtype_match = is_subtype(
                        left_item,
                        right_item,
                        self.check_type_parameter,
                        ignore_pos_arg_names=self.ignore_pos_arg_names)

                    # Order matters: we need to make sure that the index of
                    # this item is at least the index of the previous one.
                    if subtype_match and previous_match_left_index <= left_index:
                        if not found_match:
                            # Update the index of the previous match.
                            previous_match_left_index = left_index
                            found_match = True
                            matched_overloads.add(left_item)
                            possible_invalid_overloads.discard(left_item)
                    else:
                        # If this one overlaps with the supertype in any way, but it wasn't
                        # an exact match, then it's a potential error.
                        if (is_callable_compatible(
                                left_item,
                                right_item,
                                is_compat=is_subtype,
                                ignore_return=True,
                                ignore_pos_arg_names=self.ignore_pos_arg_names)
                                or is_callable_compatible(
                                    right_item,
                                    left_item,
                                    is_compat=is_subtype,
                                    ignore_return=True,
                                    ignore_pos_arg_names=self.
                                    ignore_pos_arg_names)):
                            # If this is an overload that's already been matched, there's no
                            # problem.
                            if left_item not in matched_overloads:
                                possible_invalid_overloads.add(left_item)

                if not found_match:
                    return False

            if possible_invalid_overloads:
                # There were potentially invalid overloads that were never matched to the
                # supertype.
                return False
            return True
        elif isinstance(right, UnboundType):
            return True
        elif isinstance(right, TypeType):
            # All the items must have the same type object status, so
            # it's sufficient to query only (any) one of them.
            # This is unsound, we don't check all the __init__ signatures.
            return left.is_type_obj() and is_subtype(left.items()[0], right)
        else:
            return False
예제 #37
0
파일: fixup.py 프로젝트: cocoatomo/mypy
 def visit_overloaded(self, t: Overloaded) -> None:
     for ct in t.items():
         ct.accept(self)
예제 #38
0
 def visit_overloaded(self, t: types.Overloaded) -> Set[str]:
     return self._visit(t.items()) | self._visit(t.fallback)