示例#1
0
 def test_simple_args(self):
     # type: () -> None
     self.assert_type_comment('(int) -> None',
                              ([class_arg('int')], ClassType('None')))
     self.assert_type_comment(
         '(int, str) -> bool',
         ([class_arg('int'), class_arg('str')], ClassType('bool')))
示例#2
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')))
示例#3
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)
示例#4
0
 def test_simplify_multiple_empty_collections(self):
     # type: () -> None
     self.assert_infer(
         ['() -> Tuple[List, List[x]]', '() -> Tuple[List, List]'],
         ([],
          TupleType(
              [ClassType('List'),
               ClassType('List', [ClassType('x')])])))
示例#5
0
 def test_merge_unions(self):
     # type: () -> None
     self.assert_infer(
         ['(Union[int, str]) -> None', '(Union[str, None]) -> None'],
         ([(UnionType(
             [ClassType('int'),
              ClassType('str'),
              ClassType('None')]), ARG_POS)], ClassType('None')))
示例#6
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()))
示例#7
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()))
示例#8
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()))
示例#9
0
def merged_type(t, s):
    # type: (AbstractType, AbstractType) -> Optional[AbstractType]
    """Return merged type if two items can be merged in to a different, more general type.

    Return None if merging is not possible.
    """
    if isinstance(t, TupleType) and isinstance(s, TupleType):
        if len(t.items) == len(s.items):
            return TupleType(
                [combine_types([ti, si]) for ti, si in zip(t.items, s.items)])
        all_items = t.items + s.items
        if all_items and all(item == all_items[0] for item in all_items[1:]):
            # Merge multiple compatible fixed-length tuples into a variable-length tuple type.
            return ClassType('Tuple', [all_items[0]])
    elif (isinstance(t, TupleType) and isinstance(s, ClassType)
          and s.name == 'Tuple' and len(s.args) == 1):
        if all(item == s.args[0] for item in t.items):
            # Merge fixed-length tuple and variable-length tuple.
            return s
    elif isinstance(s, TupleType) and isinstance(
            t, ClassType) and t.name == 'Tuple':
        return merged_type(s, t)
    elif isinstance(s, NoReturnType):
        return t
    elif isinstance(t, NoReturnType):
        return s
    elif isinstance(s, AnyType):
        # This seems to be usually desirable, since Anys tend to come from unknown types.
        return t
    elif isinstance(t, AnyType):
        # Similar to above.
        return s
    return None
示例#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_optional(Self):
     # type: () -> None
     assert str(UnionType([ClassType('str'),
                           ClassType('None')])) == 'Optional[str]'
     assert str(UnionType([ClassType('None'),
                           ClassType('str')])) == 'Optional[str]'
     assert str(
         UnionType([ClassType('None'),
                    ClassType('str'),
                    ClassType('int')])) == 'Union[None, str, int]'
示例#12
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
示例#13
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')))
示例#14
0
 def test_optional(self):
     # type: () -> None
     self.assert_type_comment('(Optional[int]) -> Any', ([
         Argument(UnionType([ClassType('int'),
                             ClassType('None')]), ARG_POS)
     ], AnyType()))
示例#15
0
 def test_remove_redundant_union_item(self):
     # type: () -> None
     self.assert_infer(['(str) -> None', '(unicode) -> None'],
                       ([(ClassType('Text'), ARG_POS)], ClassType('None')))
示例#16
0
 def test_infer_union_return(self):
     # type: () -> None
     self.assert_infer(['() -> int', '() -> str'],
                       ([], UnionType([ClassType('int'),
                                       ClassType('str')])))
示例#17
0
 def test_star_arg(self):
     # type: () -> None
     self.assert_infer(['(int) -> None', '(int, *bool) -> None'],
                       ([(ClassType('int'), ARG_POS),
                         (ClassType('bool'), ARG_STAR)], ClassType('None')))
示例#18
0
 def test_infer_none_argument(self):
     # type: () -> None
     self.assert_infer(['(None) -> None'], ([(UnionType(
         [ClassType('None'), AnyType()]), ARG_POS)], ClassType('None')))
示例#19
0
 def test_infer_union_arg(self):
     # type: () -> None
     self.assert_infer(['(int) -> None', '(str) -> None'], ([
         (UnionType([ClassType('int'), ClassType('str')]), ARG_POS)
     ], ClassType('None')))
示例#20
0
def class_arg(name, args=None):
    # type: (str, Optional[List[AbstractType]]) -> Argument
    return Argument(ClassType(name, args), ARG_POS)
示例#21
0
 def test_simple(self):
     # type: () -> None
     self.assert_infer(['(int) -> str'],
                       ([(ClassType('int'), ARG_POS)], ClassType('str')))
示例#22
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()))
示例#23
0
 def test_empty(self):
     # type: () -> None
     self.assert_type_comment('() -> None', ([], ClassType('None')))
示例#24
0
 def test_uniform_tuple_str(self):
     # type: () -> None
     assert str(ClassType('Tuple', [ClassType('int')])) == 'Tuple[int, ...]'
示例#25
0
 def test_tuple_type_str(self):
     # type: () -> None
     assert str(TupleType([ClassType('int')])) == 'Tuple[int]'
     assert str(TupleType([ClassType('int'),
                           ClassType('str')])) == 'Tuple[int, str]'
     assert str(TupleType([])) == 'Tuple[()]'
示例#26
0
 def test_union_type_str(Self):
     # type: () -> None
     assert str(UnionType([ClassType('int'),
                           ClassType('str')])) == 'Union[int, str]'
示例#27
0
 def test_simplify_list_item_types(self):
     # type: () -> None
     self.assert_infer(['(List[Union[bool, int]]) -> None'], ([(ClassType(
         'List', [ClassType('int')]), ARG_POS)], ClassType('None')))
示例#28
0
 def test_infer_ignore_mock(self):
     # type: () -> None
     self.assert_infer(['(mock.mock.Mock) -> None', '(str) -> None'],
                       ([(ClassType('str'), ARG_POS)], ClassType('None')))
示例#29
0
 def test_instance_str(self):
     # type: () -> None
     assert str(ClassType('int')) == 'int'
     assert str(ClassType('List', [ClassType('int')])) == 'List[int]'
     assert str(ClassType(
         'Dict', [ClassType('int'), ClassType('str')])) == 'Dict[int, str]'
示例#30
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')])))