def test_tuple_swap(self): ty = self.Infer(""" def f(x): return (x[1], x[0]) f((3, "str")) """, deep=False, show_library_calls=True) self.assertHasOnlySignatures( ty.Lookup("f"), ((pytd.TupleType(self.tuple, (self.int, self.str)),), pytd.TupleType(self.tuple, (self.str, self.int))))
def testTuplePassThrough(self): ty = self.Infer(""" def f(x): return x f((3, "str")) """, deep=False, show_library_calls=True) self.assertHasOnlySignatures( ty.Lookup("f"), ((pytd.TupleType(self.tuple, (self.int, self.str)),), pytd.TupleType(self.tuple, (self.int, self.str))))
def test_empty_tuple(self): ty = self.Infer(""" def f(): return () f() """, deep=False, show_library_calls=True) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.TupleType(self.tuple, ())))
def test_starargs_type2(self): ty = self.Infer(""" def f(nr, *args): return args f("foo", 4) """, deep=False, show_library_calls=True) self.assertHasReturnType(ty.Lookup("f"), pytd.TupleType(self.tuple, (self.int,)))
def testStarArgsType(self): ty = self.Infer(""" def f(*args, **kwds): return args f(3) """, deep=False, show_library_calls=True) self.assertHasReturnType(ty.Lookup("f"), pytd.TupleType(self.tuple, (self.int,)))
def setUpClass(cls): super().setUpClass() # We use class-wide loader to avoid creating a new loader for every test # method if not required. cls._loader = None def t(name): # pylint: disable=invalid-name return pytd.ClassType("builtins." + name) cls.bool = t("bool") cls.dict = t("dict") cls.float = t("float") cls.complex = t("complex") cls.int = t("int") cls.list = t("list") cls.none_type = t("NoneType") cls.object = t("object") cls.set = t("set") cls.frozenset = t("frozenset") cls.str = t("str") cls.bytearray = t("bytearray") cls.tuple = t("tuple") cls.unicode = t("unicode") cls.generator = t("generator") cls.function = pytd.ClassType("typing.Callable") cls.anything = pytd.AnythingType() cls.nothing = pytd.NothingType() cls.module = t("module") cls.file = t("file") # The various union types use pytd_utils.CanonicalOrdering()'s ordering: cls.intorstr = pytd.UnionType((cls.int, cls.str)) cls.strorunicode = pytd.UnionType((cls.str, cls.unicode)) cls.intorfloat = pytd.UnionType((cls.float, cls.int)) cls.intorfloatorstr = pytd.UnionType((cls.float, cls.int, cls.str)) cls.complexorstr = pytd.UnionType((cls.complex, cls.str)) cls.intorfloatorcomplex = pytd.UnionType( (cls.int, cls.float, cls.complex)) cls.int_tuple = pytd.GenericType(cls.tuple, (cls.int, )) cls.nothing_tuple = pytd.TupleType(cls.tuple, ()) cls.intorfloat_tuple = pytd.GenericType(cls.tuple, (cls.intorfloat, )) cls.int_set = pytd.GenericType(cls.set, (cls.int, )) cls.intorfloat_set = pytd.GenericType(cls.set, (cls.intorfloat, )) cls.unknown_frozenset = pytd.GenericType(cls.frozenset, (cls.anything, )) cls.float_frozenset = pytd.GenericType(cls.frozenset, (cls.float, )) cls.empty_frozenset = pytd.GenericType(cls.frozenset, (cls.nothing, )) cls.int_list = pytd.GenericType(cls.list, (cls.int, )) cls.str_list = pytd.GenericType(cls.list, (cls.str, )) cls.intorfloat_list = pytd.GenericType(cls.list, (cls.intorfloat, )) cls.intorstr_list = pytd.GenericType(cls.list, (cls.intorstr, )) cls.anything_list = pytd.GenericType(cls.list, (cls.anything, )) cls.nothing_list = pytd.GenericType(cls.list, (cls.nothing, )) cls.int_int_dict = pytd.GenericType(cls.dict, (cls.int, cls.int)) cls.int_str_dict = pytd.GenericType(cls.dict, (cls.int, cls.str)) cls.str_int_dict = pytd.GenericType(cls.dict, (cls.str, cls.int)) cls.nothing_nothing_dict = pytd.GenericType(cls.dict, (cls.nothing, cls.nothing))
def test_slice(self): ty = self.Infer(""" def f(x): a, b = x return (a, b) f((1, 2)) """, deep=False, show_library_calls=True) t = pytd.TupleType(self.tuple, (self.int, self.int)) self.assertHasSignature(ty.Lookup("f"), (t,), t)
def testVerifyHeterogeneousTuple(self): # Error: does not inherit from Generic base = pytd.ClassType("tuple") base.cls = pytd.Class("tuple", None, (), (), (), (), None, ()) t1 = pytd.TupleType(base, (pytd.NamedType("str"), pytd.NamedType("float"))) self.assertRaises(visitors.ContainerError, lambda: t1.Visit(visitors.VerifyContainers())) # Error: Generic[str, float] gen = pytd.ClassType("typing.Generic") gen.cls = pytd.Class("typing.Generic", None, (), (), (), (), None, ()) t2 = pytd.TupleType(gen, (pytd.NamedType("str"), pytd.NamedType("float"))) self.assertRaises(visitors.ContainerError, lambda: t2.Visit(visitors.VerifyContainers())) # Okay param = pytd.TypeParameter("T") parent = pytd.GenericType(gen, (param,)) base.cls = pytd.Class( "tuple", None, (parent,), (), (), (), None, (pytd.TemplateItem(param),)) t3 = pytd.TupleType(base, (pytd.NamedType("str"), pytd.NamedType("float"))) t3.Visit(visitors.VerifyContainers())
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))
def _heterogeneous_tuple(self, base_type, parameters): if parameters: return pytd.TupleType(base_type=base_type, parameters=parameters) else: return base_type
def testPrintHeterogeneousTuple(self): t = pytd.TupleType(pytd.NamedType("tuple"), (pytd.NamedType("str"), pytd.NamedType("float"))) self.assertEqual("Tuple[str, float]", pytd.Print(t))
def heterogeneous_tuple( base_type: pytd.NamedType, parameters: Parameters ) -> pytd_node.Node: return pytd.TupleType(base_type=base_type, parameters=parameters)
def _heterogeneous_tuple(self, base_type, parameters): if parameters: return pytd.TupleType(base_type=base_type, parameters=parameters) else: return pytd.GenericType(base_type=base_type, parameters=(pytd.NothingType(),))