Пример #1
0
 def test_union(self):
     # type: () -> None
     self.assert_type_comment('(Union[int, str]) -> Any', ([
         Argument(UnionType([ClassType('int'),
                             ClassType('str')]), ARG_POS)
     ], AnyType()))
     self.assert_type_comment('(Union[int]) -> Any',
                              ([class_arg('int')], AnyType()))
Пример #2
0
 def test_tuple(self):
     # type: () -> None
     self.assert_type_comment('(Tuple[]) -> Any',
                              ([tuple_arg([])], AnyType()))
     self.assert_type_comment('(Tuple[int]) -> Any',
                              ([tuple_arg([ClassType('int')])], AnyType()))
     self.assert_type_comment(
         '(Tuple[int, str]) -> Any',
         ([tuple_arg([ClassType('int'), ClassType('str')])], AnyType()))
Пример #3
0
 def test_star_args(self):
     # type: () -> None
     self.assert_type_comment(
         '(*str) -> Any',
         ([Argument(ClassType('str'), ARG_STAR)], AnyType()))
     self.assert_type_comment(
         '(int, *str) -> Any',
         ([class_arg('int'),
           Argument(ClassType('str'), ARG_STAR)], AnyType()))
Пример #4
0
def is_redundant_union_item(first, other):
    # type: (AbstractType, AbstractType) -> bool
    """If union has both items, is the first one redundant?

    For example, if first is 'str' and the other is 'Text', return True.

    If items are equal, return False.
    """
    if isinstance(first, ClassType) and isinstance(other, ClassType):
        if first.name == 'str' and other.name == 'Text':
            return True
        elif first.name == 'bool' and other.name == 'int':
            return True
        elif first.name == 'int' and other.name == 'float':
            return True
        elif (first.name in ('List', 'Dict', 'Set')
              and other.name == first.name):
            if not first.args and other.args:
                return True
            elif len(first.args) == len(other.args) and first.args:
                result = all(
                    first_arg == other_arg or other_arg == AnyType()
                    for first_arg, other_arg in zip(first.args, other.args))
                return result

    return False
Пример #5
0
def filter_ignored_items(items):
    # type: (List[AbstractType]) -> List[AbstractType]
    result = [
        item for item in items
        if not isinstance(item, ClassType) or item.name not in IGNORED_ITEMS
    ]
    return result or [AnyType()]
Пример #6
0
 def parse_type(self):
     # type: () -> AbstractType
     t = self.next()
     if not isinstance(t, DottedName):
         self.fail()
     if t.text == 'Any':
         return AnyType()
     elif t.text == 'mypy_extensions.NoReturn':
         return NoReturnType()
     elif t.text == 'Tuple':
         self.expect('[')
         args = self.parse_type_list()
         self.expect(']')
         return TupleType(args)
     elif t.text == 'Union':
         self.expect('[')
         items = self.parse_type_list()
         self.expect(']')
         if len(items) == 1:
             return items[0]
         elif len(items) == 0:
             self.fail()
         else:
             return UnionType(items)
     else:
         if self.lookup() == '[':
             self.expect('[')
             args = self.parse_type_list()
             self.expect(']')
             if t.text == 'Optional' and len(args) == 1:
                 return UnionType([args[0], ClassType('None')])
             return ClassType(t.text, args)
         else:
             return ClassType(t.text)
Пример #7
0
 def test_remove_redundant_dict_item_when_simplified(self):
     # type: () -> None
     self.assert_infer([
         '(Dict[str, Any]) -> None',
         '(Dict[str, Union[str, List, Dict, int]]) -> None'
     ], ([(ClassType('Dict', [ClassType('str'), AnyType()]), ARG_POS)
          ], ClassType('None')))
Пример #8
0
def infer_annotation(type_comments):
    # type: (List[str]) -> Tuple[List[Argument], AbstractType]
    """Given some type comments, return a single inferred signature.

    Args:
        type_comments: Strings of form '(arg1, ... argN) -> ret'

    Returns: Tuple of (argument types and kinds, return type).
    """
    assert type_comments
    args = {}  # type: Dict[int, Set[Argument]]
    returns = set()
    for comment in type_comments:
        arg_types, return_type = parse_type_comment(comment)
        for i, arg_type in enumerate(arg_types):
            args.setdefault(i, set()).add(arg_type)
        returns.add(return_type)
    combined_args = []
    for i in sorted(args):
        arg_infos = list(args[i])
        kind = argument_kind(arg_infos)
        if kind is None:
            raise InferError('Ambiguous argument kinds:\n' +
                             '\n'.join(type_comments))
        types = [arg.type for arg in arg_infos]
        combined = combine_types(types)
        if str(combined) == 'None':
            # It's very rare for an argument to actually be typed `None`, more likely than
            # not we simply don't have any data points for this argument.
            combined = UnionType([ClassType('None'), AnyType()])
        if kind != ARG_POS and (len(str(combined)) > 120
                                or isinstance(combined, UnionType)):
            # Avoid some noise.
            combined = AnyType()
        combined_args.append(Argument(combined, kind))
    combined_return = combine_types(returns)
    return combined_args, combined_return
Пример #9
0
def simplify_types(types):
    # type: (Iterable[AbstractType]) -> List[AbstractType]
    """Given some types, give simplified types representing the union of types."""
    flattened = flatten_types(types)
    items = filter_ignored_items(flattened)
    items = [simplify_recursive(item) for item in items]
    items = merge_items(items)
    items = dedupe_types(items)
    # We have to remove reundant items after everything has been simplified and
    # merged as this simplification may be what makes items redundant.
    items = remove_redundant_items(items)
    if len(items) > 3:
        return [AnyType()]
    else:
        return items
Пример #10
0
def simplify_recursive(typ):
    # type: (AbstractType) -> AbstractType
    """Simplify all components of a type."""
    if isinstance(typ, UnionType):
        return combine_types(typ.items)
    elif isinstance(typ, ClassType):
        simplified = ClassType(typ.name,
                               [simplify_recursive(arg) for arg in typ.args])
        args = simplified.args
        if (simplified.name == 'Dict' and len(args) == 2
                and isinstance(args[0], ClassType)
                and args[0].name in ('str', 'Text')
                and isinstance(args[1], UnionType)
                and not is_optional(args[1])):
            # Looks like a potential case for TypedDict, which we don't properly support yet.
            return ClassType('Dict', [args[0], AnyType()])
        return simplified
    elif isinstance(typ, TupleType):
        return TupleType([simplify_recursive(item) for item in typ.items])
    return typ
Пример #11
0
 def test_simplify_potential_typed_dict(self):
     # type: () -> None
     # Fall back to Dict[x, Any] in case of a complex Dict type.
     self.assert_infer(['(Dict[str, Union[int, str]]) -> Any'], ([
         (ClassType('Dict', [ClassType('str'), AnyType()]), ARG_POS)
     ], AnyType()))
     self.assert_infer(
         ['(Dict[Text, Union[int, str]]) -> Any'], ([(ClassType(
             'Dict', [ClassType('Text'), AnyType()]), ARG_POS)], AnyType()))
     # Not a potential TypedDict so ordinary simplification applies.
     self.assert_infer(['(Dict[str, Union[str, Text]]) -> Any'], ([
         (ClassType('Dict',
                    [ClassType('str'), ClassType('Text')]), ARG_POS)
     ], AnyType()))
     self.assert_infer(['(Dict[str, Union[int, None]]) -> Any'],
                       ([(ClassType('Dict', [
                           ClassType('str'),
                           UnionType([ClassType('int'),
                                      ClassType('None')])
                       ]), ARG_POS)], AnyType()))
Пример #12
0
 def test_remove_redundant_dict_item(self):
     # type: () -> None
     self.assert_infer(
         ['(Dict[str, Any]) -> None', '(Dict[str, str]) -> None'],
         ([(ClassType('Dict', [ClassType('str'),
                               AnyType()]), ARG_POS)], ClassType('None')))
Пример #13
0
 def test_infer_none_argument(self):
     # type: () -> None
     self.assert_infer(['(None) -> None'], ([(UnionType(
         [ClassType('None'), AnyType()]), ARG_POS)], ClassType('None')))
Пример #14
0
 def test_infer_ignore_mock_fallback_to_any(self):
     # type: () -> None
     self.assert_infer(
         ['(mock.mock.Mock) -> str', '(mock.mock.Mock) -> int'], ([
             (AnyType(), ARG_POS)
         ], UnionType([ClassType('str'), ClassType('int')])))
Пример #15
0
 def test_any_type_str(self):
     # type: () -> None
     assert str(AnyType()) == 'Any'
Пример #16
0
def any_arg():
    # type: () -> Argument
    return Argument(AnyType(), ARG_POS)
Пример #17
0
 def test_unicode(self):
     # type: () -> None
     self.assert_type_comment('(unicode) -> Any',
                              ([class_arg('Text')], AnyType()))
Пример #18
0
 def test_function(self):
     # type: () -> None
     self.assert_type_comment('(function) -> Any',
                              ([class_arg('Callable')], AnyType()))
Пример #19
0
 def test_optional(self):
     # type: () -> None
     self.assert_type_comment('(Optional[int]) -> Any', ([
         Argument(UnionType([ClassType('int'),
                             ClassType('None')]), ARG_POS)
     ], AnyType()))
Пример #20
0
 def test_any_and_unknown(self):
     # type: () -> None
     self.assert_type_comment(
         '(Any) -> pyannotate_runtime.collect_types.UnknownType',
         ([any_arg()], AnyType()))