Ejemplo n.º 1
0
 def testTuplePassThrough(self):
     ty = self.Infer("""
   def f(x):
     return x
   f((3, "str"))
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False)
     self.assertHasOnlySignatures(
         ty.Lookup("f"),
         ((pytd.HomogeneousContainerType(self.tuple, (self.intorstr, )), ),
          pytd.HomogeneousContainerType(self.tuple, (self.intorstr, ))))
Ejemplo n.º 2
0
 def testTupleSwap(self):
     with self.Infer("""
   def f(x):
     return (x[1], x[0])
   f((3, "str"))
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False) as ty:
         self.assertHasOnlySignatures(
             ty.Lookup("f"),
             ((pytd.HomogeneousContainerType(self.tuple,
                                             (self.intorstr, )), ),
              pytd.HomogeneousContainerType(self.tuple, (self.intorstr, ))))
Ejemplo n.º 3
0
 def testTypingContainer(self):
     cls = self._vm.convert.list_type.bindings[0].data
     container = abstract.AnnotationContainer("List", self._vm, cls)
     expected = pytd.HomogeneousContainerType(
         pytd.NamedType("__builtin__.list"), (pytd.AnythingType(), ))
     actual = container.get_instance_type(self._vm.root_cfg_node)
     self.assertEquals(expected, actual)
Ejemplo n.º 4
0
def convert_string_type(string_type, unknown, mapping, global_lookup, depth=0):
    """Convert a string representing a type back to a pytd type."""
    try:
        # Check whether this is a type declared in a pytd.
        cls = global_lookup.Lookup(string_type)
        base_type = pytd_utils.NamedOrClassType(cls.name, cls)
    except KeyError:
        # If we don't have a pytd for this type, it can't be a template.
        cls = None
        base_type = pytd_utils.NamedOrClassType(string_type, cls)

    if cls and cls.template:
        parameters = []
        for t in cls.template:
            type_param_name = unknown + "." + string_type + "." + t.name
            if type_param_name in mapping and depth < MAX_DEPTH:
                string_type_params = mapping[type_param_name]
                parameters.append(
                    convert_string_type_list(string_type_params, unknown,
                                             mapping, global_lookup,
                                             depth + 1))
            else:
                parameters.append(pytd.AnythingType())
        if len(parameters) == 1:
            return pytd.HomogeneousContainerType(base_type, tuple(parameters))
        else:
            return pytd.GenericType(base_type, tuple(parameters))
    else:
        return base_type
Ejemplo n.º 5
0
def MakeClassOrContainerType(base_type, type_arguments):
    """If we have type params, build a generic type, a normal type otherwise."""
    if len(type_arguments) == 0:
        return base_type
    elif len(type_arguments) == 1:
        return pytd.HomogeneousContainerType(base_type, tuple(type_arguments))
    else:
        return pytd.GenericType(base_type, tuple(type_arguments))
Ejemplo n.º 6
0
def _star_param(name, param_type):
    """Return a pytd.Parameter for a *args argument."""
    if param_type is None:
        param_type = pytd.NamedType("tuple")
    else:
        param_type = pytd.HomogeneousContainerType(pytd.NamedType("tuple"),
                                                   (param_type, ))
    return pytd.Parameter(name, param_type, False, True, None)
Ejemplo n.º 7
0
 def testListLiteral(self):
   ty = self.Infer("""
     def f():
       return [1, 2, 3]
     f()
   """, deep=False, solve_unknowns=False, show_library_calls=True)
   self.assertHasOnlySignatures(
       ty.Lookup("f"),
       ((), pytd.HomogeneousContainerType(self.list, (self.int,))))
Ejemplo n.º 8
0
 def testEmptyTuple(self):
   ty = self.Infer("""
     def f():
       return ()
     f()
   """, deep=False, solve_unknowns=False, show_library_calls=True)
   self.assertHasOnlySignatures(
       ty.Lookup("f"),
       ((), pytd.HomogeneousContainerType(self.tuple, (pytd.NothingType(),))))
Ejemplo n.º 9
0
def MakeClassOrContainerType(base_type, type_arguments, homogeneous):
    """If we have type params, build a generic type, a normal type otherwise."""
    if homogeneous:
        assert len(type_arguments) == 1
        return pytd.HomogeneousContainerType(base_type, tuple(type_arguments))
    elif base_type.name in ("__builtin__.tuple", "typing.Tuple"):
        return pytd.TupleType(base_type, tuple(type_arguments))
    elif not type_arguments:
        return base_type
    else:
        return pytd.GenericType(base_type, tuple(type_arguments))
Ejemplo n.º 10
0
 def testSetsSanity(self):
   ty = self.Infer("""
     def f():
       x = set([1])
       x.add(10)
       return x
     f()
   """, deep=False, solve_unknowns=False, show_library_calls=True)
   self.assertHasOnlySignatures(
       ty.Lookup("f"),
       ((), pytd.HomogeneousContainerType(self.set, (self.int,))))
Ejemplo n.º 11
0
 def testListLiteral(self):
     with self.Infer("""
   def f():
     return [1, 2, 3]
   f()
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False) as ty:
         self.assertHasOnlySignatures(
             ty.Lookup("f"),
             ((), pytd.HomogeneousContainerType(self.list, (self.int, ))))
Ejemplo n.º 12
0
 def testListConcatUnlike(self):
   ty = self.Infer("""
     def f():
       x = []
       x.append(1)
       x.append(2)
       x.append(3)
       return ["str"] + x
     f()
   """, deep=False, solve_unknowns=False, show_library_calls=True)
   self.assertHasOnlySignatures(
       ty.Lookup("f"),
       ((), pytd.HomogeneousContainerType(self.list, (self.intorstr,))))
Ejemplo n.º 13
0
 def testEmptyTuple(self):
     with self.Infer("""
   def f():
     return ()
   f()
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False) as ty:
         self.assertHasOnlySignatures(
             ty.Lookup("f"),
             ((),
              pytd.HomogeneousContainerType(self.tuple,
                                            (pytd.NothingType(), ))))
Ejemplo n.º 14
0
 def testSetsAdd(self):
     ty = self.Infer("""
   def f():
     x = set([])
     x.add(1)
     x.add(10)
     return x
   f()
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False)
     self.assertHasOnlySignatures(
         ty.Lookup("f"),
         ((), pytd.HomogeneousContainerType(self.set, (self.int, ))))
Ejemplo n.º 15
0
 def testListConcatMultiType(self):
   ty = self.Infer("""
     def f():
       x = []
       x.append(1)
       x.append("str")
       return x + [1.3] + x
     f()
   """, deep=False, solve_unknowns=False, show_library_calls=True)
   self.assertHasOnlySignatures(
       ty.Lookup("f"),
       ((),
        pytd.HomogeneousContainerType(
            self.list,
            (pytd.UnionType((self.int, self.float, self.str)),))))
Ejemplo n.º 16
0
 def testSetsSanity(self):
     with self.Infer("""
   def f():
     x = set([1])
     x.add(10)
     return x
   f()
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False) as ty:
         self.assertHasOnlySignatures(
             ty.Lookup("f"),
             ((),
              pytd.HomogeneousContainerType(pytd.ClassType("set"),
                                            (self.int, ))))
Ejemplo n.º 17
0
 def testListConcat(self):
     with self.Infer("""
   def f():
     x = []
     x.append(1)
     x.append(2)
     x.append(3)
     return [0] + x
   f()
 """,
                     deep=False,
                     solve_unknowns=False,
                     extract_locals=False) as ty:
         self.assertHasOnlySignatures(
             ty.Lookup("f"),
             ((), pytd.HomogeneousContainerType(self.list, (self.int, ))))
Ejemplo n.º 18
0
 def p_type_homogeneous(self, p):
     """type : named_or_external_type LBRACKET parameters RBRACKET"""
     _, base_type, _, parameters, _ = p
     if p[1] == pytd.NamedType('Union'):
         p[0] = pytd.UnionType(parameters)
     elif p[1] == pytd.NamedType('Optional'):
         p[0] = pytd.UnionType(parameters[0], pytd.NamedType('None'))
     elif len(parameters) == 2 and parameters[-1] is Ellipsis:
         element_type, _ = parameters
         if element_type is Ellipsis:
             make_syntax_error(self, '[..., ...] not supported', p)
         p[0] = pytd.HomogeneousContainerType(base_type=base_type,
                                              parameters=(element_type, ))
     else:
         parameters = tuple(pytd.AnythingType() if p is Ellipsis else p
                            for p in parameters)
         p[0] = pytd.GenericType(base_type=base_type, parameters=parameters)
Ejemplo n.º 19
0
 def _parameterized_type(self, base_type, parameters):
     """Return a parameterized type."""
     if base_type == pytd.NamedType("typing.Callable"):
         # TODO(kramm): Support Callable[[params], ret].
         return base_type
     elif len(parameters) == 2 and parameters[-1] is self.ELLIPSIS:
         element_type = parameters[0]
         if element_type is self.ELLIPSIS:
             raise ParseError("[..., ...] not supported")
         return pytd.HomogeneousContainerType(base_type=base_type,
                                              parameters=(element_type, ))
     else:
         parameters = tuple(pytd.AnythingType() if p is self.ELLIPSIS else p
                            for p in parameters)
         if self._is_tuple_base_type(base_type):
             return self._heterogeneous_tuple(base_type, parameters)
         else:
             assert parameters
             return pytd.GenericType(base_type=base_type,
                                     parameters=parameters)
Ejemplo n.º 20
0
  def setUp(self):
    self.bool = pytd.ClassType("bool")
    self.dict = pytd.ClassType("dict")
    self.float = pytd.ClassType("float")
    self.complex = pytd.ClassType("complex")
    self.int = pytd.ClassType("int")
    if self.PYTHON_VERSION[0] == 2:
      self.long = pytd.ClassType("long")
    self.list = pytd.ClassType("list")
    self.none_type = pytd.ClassType("NoneType")
    self.object = pytd.ClassType("object")
    self.set = pytd.ClassType("set")
    self.frozenset = pytd.ClassType("frozenset")
    self.str = pytd.ClassType("str")
    self.bytes = pytd.ClassType("bytes")
    self.bytearray = pytd.ClassType("bytearray")
    self.tuple = pytd.ClassType("tuple")
    self.unicode = pytd.ClassType("unicode")
    self.generator = pytd.ClassType("generator")
    self.function = pytd.ClassType("function")
    self.anything = pytd.AnythingType()
    self.nothing = pytd.NothingType()
    self.module = pytd.ClassType("module")
    self.file = pytd.ClassType("file")

    # The various union types use pytd_utils.CanonicalOrdering()'s ordering:
    self.intorstr = pytd.UnionType((self.int, self.str))
    self.strorunicodeorbytes = pytd.UnionType(
        (self.str, self.unicode, self.bytes))
    self.intorfloat = pytd.UnionType((self.float, self.int))
    self.intorfloatorstr = pytd.UnionType((self.float, self.int, self.str))
    self.complexorstr = pytd.UnionType((self.complex, self.str))
    # TODO(pludemann): fix the boolorintor... stuff when __builtins__
    #                  is modified to exclude bool from the result
    if self.PYTHON_VERSION[0] == 3:
      self.intorfloatorlong = self.intorfloat
      self.intorfloatorlongorcomplex = pytd.UnionType(
          (self.int, self.float, self.complex))
    else:
      self.intorfloatorlong = pytd.UnionType((self.int, self.float, self.long))
      self.boolorintorfloatorlongorcomplex = pytd.UnionType(
          (self.bool, self.int, self.float, self.long, self.complex))
    self.int_tuple = pytd.HomogeneousContainerType(self.tuple, (self.int,))
    self.nothing_tuple = pytd.HomogeneousContainerType(self.tuple,
                                                       (self.nothing,))
    self.intorfloat_tuple = pytd.HomogeneousContainerType(self.tuple,
                                                          (self.intorfloat,))
    self.int_set = pytd.HomogeneousContainerType(self.set, (self.int,))
    self.intorfloat_set = pytd.HomogeneousContainerType(self.set,
                                                        (self.intorfloat,))
    # TODO(pludemann): simplify this (test_and2)
    self.unknown_frozenset = pytd.HomogeneousContainerType(
        self.frozenset, (self.anything,))
    self.float_frozenset = pytd.HomogeneousContainerType(self.frozenset,
                                                         (self.float,))
    self.empty_frozenset = pytd.HomogeneousContainerType(self.frozenset,
                                                         (self.nothing,))
    self.int_list = pytd.HomogeneousContainerType(self.list, (self.int,))
    self.str_list = pytd.HomogeneousContainerType(self.list, (self.str,))
    self.intorfloat_list = pytd.HomogeneousContainerType(self.list,
                                                         (self.intorfloat,))
    self.intorstr_list = pytd.HomogeneousContainerType(self.list,
                                                       (self.intorstr,))
    self.anything_list = pytd.HomogeneousContainerType(self.list,
                                                       (self.anything,))
    self.nothing_list = pytd.HomogeneousContainerType(self.list,
                                                      (self.nothing,))
    self.int_int_dict = pytd.GenericType(self.dict, (self.int, self.int))
    self.int_str_dict = pytd.GenericType(self.dict, (self.int, self.str))
    self.str_int_dict = pytd.GenericType(self.dict, (self.str, self.int))
    self.nothing_nothing_dict = pytd.GenericType(self.dict,
                                                 (self.nothing, self.nothing))
Ejemplo n.º 21
0
  def VisitUnionType(self, union):
    """Push unions down into containers.

    This collects similar container types in unions and merges them into
    single instances with the union type pushed down to the element_type level.

    Arguments:
      union: A pytd.Union instance. Might appear in a parameter, a return type,
        a constant type, etc.

    Returns:
      A simplified pytd.Union.
    """
    if not any(isinstance(t, pytd.GenericType) for t in union.type_list):
      # Optimization: If we're not going to change anything, return original.
      return union
    union = utils.JoinTypes(union.type_list)  # flatten
    if not isinstance(union, pytd.UnionType):
      union = pytd.UnionType((union,))
    merge_tuples = True
    tuple_length = None
    for t in union.type_list:
      if isinstance(t, pytd.TupleType):
        if tuple_length is None:
          tuple_length = len(t.parameters)
        elif tuple_length != len(t.parameters):
          break
      elif (isinstance(t, pytd.HomogeneousContainerType) and
            t.base_type.name in ("__builtin__.tuple", "typing.Tuple")):
        break
    else:
      merge_tuples = False
    if merge_tuples:
      # If our union contains homogeneous tuples, or heterogeneous tuples of
      # differing lengths, we want to turn all of the tuples into homogeneous
      # ones so that they can be merged into a single container.
      type_list = tuple(
          pytd.HomogeneousContainerType(
              base_type=t.base_type,
              parameters=(pytd.UnionType(t.parameters),))
          if isinstance(t, pytd.TupleType) else t for t in union.type_list)
      union = union.Replace(type_list=type_list)
    collect = {}
    has_redundant_base_types = False
    for t in union.type_list:
      if isinstance(t, pytd.GenericType):
        key = self._key(t)
        if key in collect:
          has_redundant_base_types = True
          collect[key] = tuple(
              utils.JoinTypes([p1, p2])
              for p1, p2 in zip(collect[key], t.parameters))
        else:
          collect[key] = t.parameters
    if not has_redundant_base_types:
      return union
    result = pytd.NothingType()
    done = set()
    for t in union.type_list:
      if isinstance(t, pytd.GenericType):
        key = self._key(t)
        if key in done:
          continue  # already added
        parameters = collect[key]
        add = t.Replace(parameters=tuple(p.Visit(CombineContainers())
                                         for p in parameters))
        done.add(key)
      else:
        add = t
      result = utils.JoinTypes([result, add])
    return result
Ejemplo n.º 22
0
  def setUp(self):
    self.options = config.Options.create(python_version=self.PYTHON_VERSION,
                                         python_exe=self.PYTHON_EXE)
    def t(name):  # pylint: disable=invalid-name
      return pytd.ClassType("__builtin__." + name)
    self.bool = t("bool")
    self.dict = t("dict")
    self.float = t("float")
    self.complex = t("complex")
    self.int = t("int")
    if self.PYTHON_VERSION[0] == 2:
      self.long = t("long")
    self.list = t("list")
    self.none_type = t("NoneType")
    self.object = t("object")
    self.set = t("set")
    self.frozenset = t("frozenset")
    self.str = t("str")
    self.bytearray = t("bytearray")
    self.tuple = t("tuple")
    self.unicode = t("unicode")
    self.generator = t("generator")
    self.function = t("function")
    self.anything = pytd.AnythingType()
    self.nothing = pytd.NothingType()
    self.module = t("module")
    self.file = t("file")

    # The various union types use pytd_utils.CanonicalOrdering()'s ordering:
    self.intorstr = pytd.UnionType((self.int, self.str))
    self.strorunicode = pytd.UnionType((self.str, self.unicode))
    self.intorfloat = pytd.UnionType((self.float, self.int))
    self.intorfloatorstr = pytd.UnionType((self.float, self.int, self.str))
    self.complexorstr = pytd.UnionType((self.complex, self.str))
    if self.PYTHON_VERSION[0] == 3:
      self.intorfloatorlong = self.intorfloat
      self.intorfloatorlongorcomplex = pytd.UnionType(
          (self.int, self.float, self.complex))
    else:
      self.intorfloatorlong = pytd.UnionType((self.int, self.float, self.long))
      self.intorfloatorlongorcomplex = pytd.UnionType(
          (self.int, self.float, self.long, self.complex))
    self.int_tuple = pytd.HomogeneousContainerType(self.tuple, (self.int,))
    self.nothing_tuple = pytd.HomogeneousContainerType(self.tuple,
                                                       (self.nothing,))
    self.intorfloat_tuple = pytd.HomogeneousContainerType(self.tuple,
                                                          (self.intorfloat,))
    self.int_set = pytd.HomogeneousContainerType(self.set, (self.int,))
    self.intorfloat_set = pytd.HomogeneousContainerType(self.set,
                                                        (self.intorfloat,))
    # TODO(pludemann): simplify this (test_and2)
    self.unknown_frozenset = pytd.HomogeneousContainerType(
        self.frozenset, (self.anything,))
    self.float_frozenset = pytd.HomogeneousContainerType(self.frozenset,
                                                         (self.float,))
    self.empty_frozenset = pytd.HomogeneousContainerType(self.frozenset,
                                                         (self.nothing,))
    self.int_list = pytd.HomogeneousContainerType(self.list, (self.int,))
    self.str_list = pytd.HomogeneousContainerType(self.list, (self.str,))
    self.intorfloat_list = pytd.HomogeneousContainerType(self.list,
                                                         (self.intorfloat,))
    self.intorstr_list = pytd.HomogeneousContainerType(self.list,
                                                       (self.intorstr,))
    self.anything_list = pytd.HomogeneousContainerType(self.list,
                                                       (self.anything,))
    self.nothing_list = pytd.HomogeneousContainerType(self.list,
                                                      (self.nothing,))
    self.int_int_dict = pytd.GenericType(self.dict, (self.int, self.int))
    self.int_str_dict = pytd.GenericType(self.dict, (self.int, self.str))
    self.str_int_dict = pytd.GenericType(self.dict, (self.str, self.int))
    self.nothing_nothing_dict = pytd.GenericType(self.dict,
                                                 (self.nothing, self.nothing))