def testTupleSwap(self): ty = self.InferDedent(""" def f(x): return (x[1], x[0]) f((3, "str")) """) self.assertHasOnlySignatures( ty.Lookup("f"), ((pytd.GenericType(self.tuple, (self.intorstr, )), ), pytd.GenericType(self.tuple, (self.intorstr, ))))
def testListLiteral(self): ty = self.InferDedent(""" def f(): return [1, 2, 3] f() """) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.GenericType(self.list, (self.int, ))))
def ClassAsType(cls): """Converts a pytd.Class to an instance of pytd.Type.""" params = tuple(item.type_param for item in cls.template) if not params: return pytd.NamedType(cls.name) elif len(params) == 1: return pytd.HomogeneousContainerType(pytd.NamedType(cls.name), params) else: # len(cls.template) >= 2 return pytd.GenericType(pytd.NamedType(cls.name), params)
def testDictLiteral(self): ty = self.InferDedent(""" def f(): return {"test": 1, "arg": 42} f() """) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.GenericType(self.dict, (self.str, self.int))))
def testEmptyTuple(self): ty = self.InferDedent(""" def f(): return () f() """) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.GenericType(self.tuple, (self.object, ))))
def p_type_homogeneous(self, p): """type : NAME LBRACKET parameters RBRACKET""" if len(p[3]) == 1: element_type, = p[3] p[0] = pytd.HomogeneousContainerType(base_type=pytd.NamedType( p[1]), parameters=(element_type, )) else: p[0] = pytd.GenericType(base_type=pytd.NamedType(p[1]), parameters=p[3])
def testSetsSanity(self): ty = self.InferDedent(""" def f(): x = set([1]) x.add(10) return x f() """) self.assertHasOnlySignatures(ty.Lookup("f"), ((), pytd.GenericType(pytd.ClassType("set"), (self.int,))))
def testDictUpdate(self): ty = self.InferDedent(""" def f(): d = {} d["test"] = 1 d["arg"] = 42 return d f() """) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.GenericType(self.dict, (self.str, self.int))))
def testListConcat(self): ty = self.InferDedent(""" def f(): x = [] x.append(1) x.append(2) x.append(3) return [0] + x f() """) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.GenericType(self.list, (self.int, ))))
def testListConcatMultiType(self): ty = self.InferDedent(""" def f(): x = [] x.append(1) x.append("str") return x + [1.3] + x f() """) self.assertHasOnlySignatures( ty.Lookup("f"), ((), pytd.GenericType(self.list, (pytd.UnionType( (self.int, self.float, self.str)), ))))
def ConvertToType(module, type_node): """Helper for converting a type node to a valid Python type. Args: module: The module to look up symbols/types type_node: A type node to convert into a python type Returns: A valid Python type. Note that None is considered a type in the declaration language, but a value in Python. So a string None is converted to a NoneType. We use the module object to look up potential type definitions defined inside that module. Raises: TypeError: if the type node passed is not supported/unknown """ # TODO: Convert this to a visitor. # clean up str if isinstance(type_node, pytd.NamedType): if type_node.name == "None": return types.NoneType elif type_node.name == "generator": return types.GeneratorType else: res = _EvalWithModuleContext(type_node.name, module) assert isinstance(res, type), (type_node.name, repr(res)) return res elif isinstance(type_node, pytd.UnionType): return pytd.UnionType([ConvertToType(module, t) for t in type_node.type_list]) elif isinstance(type_node, pytd.IntersectionType): return pytd.IntersectionType([ConvertToType(module, t) for t in type_node.type_list]) elif isinstance(type_node, pytd.GenericType): return pytd.GenericType(ConvertToType(module, type_node.base_type), type_node.parameters) elif isinstance(type_node, pytd.HomogeneousContainerType): return pytd.HomogeneousContainerType(ConvertToType(module, type_node.base_type), ConvertToType(module, type_node.element_type)) else: raise TypeError("Unknown type of type_node: {!r}".format(type_node))
def testSets(self): ty = self.InferDedent(""" def f(): x = set([1,2,3]) if x: x = x | set() y = x return x else: x.add(10) return x f() """) self.assertHasOnlySignatures(ty.Lookup("f"), ((), pytd.GenericType(pytd.ClassType("set"), (self.int,))))
def testOrder(self): # pytd types' primary sort key is the class name, second sort key is # the contents when interpreted as a (named)tuple. nodes = [ pytd.AnythingType(), pytd.GenericType(self.list, (self.int, )), pytd.NamedType("int"), pytd.NothingType(), pytd.UnionType(self.float), pytd.UnionType(self.int) ] for n1, n2 in zip(nodes[:-1], nodes[1:]): self.assertLess(n1, n2) self.assertLessEqual(n1, n2) self.assertGreater(n2, n1) self.assertGreaterEqual(n2, n1) for p in itertools.permutations(nodes): self.assertEquals(list(sorted(p)), nodes)
def testSelf(self): """Test handling of self.""" data = textwrap.dedent(""" class MyClass<U, V>: def f1(self) -> ? """) result = self.Parse(data) myclass = result.Lookup("MyClass") self.assertEquals([t.name for t in myclass.template], ["U", "V"]) f = myclass.Lookup("f1").signatures[0] self_param = f.params[0] self.assertEquals(self_param.name, "self") u, v = myclass.template self.assertEquals(self_param.type, pytd.GenericType(pytd.NamedType("MyClass"), (u.type_param, v.type_param)))
def p_type_generic_1(self, p): """type : NAME LBRACKET parameters COMMA RBRACKET""" p[0] = pytd.GenericType(base_type=pytd.NamedType(p[1]), parameters=p[3])
def testNamedAgainstGeneric(self): m = type_match.TypeMatch({}) eq = m.match_type_against_type( pytd.GenericType(pytd.NamedType("A"), []), pytd.NamedType("A"), {}) self.assertEquals(eq, booleq.TRUE)