def __init__(self, replace_unknown=False, force=False): self.class_types = [] # allow nested classes self.force = force self.replaced_self_types = (pytd.NamedType("object"), pytd.ClassType("object")) if replace_unknown: self.replaced_self_types += (pytd.AnythingType(), )
def maybe_lookup_type_param(self, t, subst): if not isinstance(t, pytd.TypeParameter): return t # We can only have type parameters in a class, and if so, we should have # added them to the type paramter substitution map (subst) beforehand: assert t in subst if subst[t] is None: # Function type parameter. Can be anything. return pytd.AnythingType() else: return subst[t]
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 testTypeMatcher(self): """Test for the TypeMatcher class.""" class MyTypeMatcher(utils.TypeMatcher): def default_match(self, t1, t2, mykeyword): assert mykeyword == "foobar" return t1 == t2 def match_function_against_function(self, f1, f2, mykeyword): assert mykeyword == "foobar" return all( self.match(sig1, sig2, mykeyword) for sig1, sig2 in zip(f1.signatures, f2.signatures)) s1 = pytd.Signature((), pytd.NothingType(), (), (), False) s2 = pytd.Signature((), pytd.AnythingType(), (), (), False) match1 = MyTypeMatcher().match(pytd.Function("f1", (s1, s2)), pytd.Function("f2", (s1, s2)), mykeyword="foobar") self.assertEquals(match1, True) match2 = MyTypeMatcher().match(pytd.Function("f1", (s1, s2)), pytd.Function("f2", (s2, s2)), mykeyword="foobar") self.assertEquals(match2, False)
def JoinTypes(types): """Combine a list of types into a union type, if needed. Leaves singular return values alone, or wraps a UnionType around them if there are multiple ones, or if there are no elements in the list (or only NothingType) return NothingType. Arguments: types: A list of types. This list might contain other UnionTypes. If so, they are flattened. Returns: A type that represents the union of the types passed in. Order is preserved. """ queue = collections.deque(types) seen = set() new_types = [] while queue: t = queue.popleft() if isinstance(t, pytd.UnionType): queue.extendleft(reversed(t.type_list)) elif isinstance(t, pytd.NothingType): pass elif t not in seen: new_types.append(t) seen.add(t) if len(new_types) == 1: return new_types.pop() elif any(isinstance(t, pytd.AnythingType) for t in new_types): return pytd.AnythingType() elif new_types: return pytd.UnionType( tuple(new_types)) # tuple() to make unions hashable else: return pytd.NothingType()
def p_type_unknown(self, p): """type : QUESTIONMARK""" p[0] = pytd.AnythingType()
def testUnknown(self): m = type_match.TypeMatch({}) eq = m.match_type_against_type(pytd.AnythingType(), pytd.AnythingType(), {}) self.assertEquals(eq, booleq.TRUE)
def VisitNamedType(self, t): if t.name.startswith("~unknown"): return pytd.AnythingType() else: return t
def testJoinAnythingTypes(self): """Test that JoinTypes() simplifies unions containing '?'.""" types = [pytd.AnythingType(), pytd.NamedType("a")] self.assertIsInstance(utils.JoinTypes(types), pytd.AnythingType)
def VisitSignature(self, sig): return sig.Replace(return_type=sig.return_type.Visit( CollapseLongUnions(self.max_length, pytd.AnythingType())))