def testMaybeInPlaceFillInClasses(self): src = textwrap.dedent(""" class A(object): def a(self, a: A, b: B) -> A or B raises A, B """) tree = self.Parse(src) ty_a = pytd.ClassType("A") visitors.InPlaceFillInClasses(ty_a, tree) self.assertIsNotNone(ty_a.cls) ty_b = pytd.ClassType("B") visitors.InPlaceFillInClasses(ty_b, tree) self.assertIsNone(ty_b.cls)
def value_to_pytd_type(self, node, v, seen, view): """Get a PyTD type representing this object, as seen at a node. Args: node: The node from which we want to observe this object. v: The object. seen: The set of values seen before while computing the type. view: A Variable -> binding map. Returns: A PyTD type. """ if isinstance(v, (abstract.Empty, abstract.Nothing)): return pytd.NothingType() elif isinstance(v, abstract.TypeParameterInstance): if (v.name in v.instance.type_parameters and v.instance.type_parameters[v.name].bindings): return pytd_utils.JoinTypes( self.value_to_pytd_type(node, p, seen, view) for p in v.instance.type_parameters[v.name].data) else: # The type parameter was never initialized return pytd.AnythingType() elif isinstance(v, (abstract.Function, abstract.IsInstance, abstract.BoundFunction)): return pytd.NamedType("typing.Callable") elif isinstance(v, abstract.Class): param = self.value_instance_to_pytd_type(node, v, None, seen, view) return pytd.GenericType(base_type=pytd.NamedType("__builtin__.type"), parameters=(param,)) elif isinstance(v, abstract.Module): return pytd.NamedType("__builtin__.module") elif isinstance(v, abstract.SimpleAbstractValue): if v.cls: classvalues = self._get_values(node, v.cls, view) cls_types = [] for cls in classvalues: cls_types.append(self.value_instance_to_pytd_type( node, cls, v, seen=seen, view=view)) ret = pytd_utils.JoinTypes(cls_types) visitors.InPlaceFillInClasses(ret, v.vm.loader.builtins) return ret else: # We don't know this type's __class__, so return AnythingType to # indicate that we don't know anything about what this is. # This happens e.g. for locals / globals, which are returned from the # code in class declarations. log.info("Using ? for %s", v.name) return pytd.AnythingType() elif isinstance(v, abstract.Union): return pytd.UnionType(tuple(self.value_to_pytd_type(node, o, seen, view) for o in v.options)) elif isinstance(v, abstract.SuperInstance): return pytd.NamedType("__builtin__.super") elif isinstance(v, abstract.Unsolvable): return pytd.AnythingType() elif isinstance(v, abstract.Unknown): return pytd.NamedType(v.class_name) else: raise NotImplementedError(v.__class__.__name__)