def _resolve_external_types(self, ast): try: ast = ast.Visit( visitors.LookupExternalTypes(self._get_module_map(), self_name=ast.name, module_alias_map=self._aliases)) except KeyError as e: raise BadDependencyError(utils.message(e), ast.name) return ast
def _resolve_external_types(self, pyval, ast_name=None): name = ast_name or pyval.name try: pyval = pyval.Visit(visitors.LookupExternalTypes( self._get_module_map(), self_name=name, module_alias_map=self._aliases)) except KeyError as e: raise BadDependencyError(utils.message(e), name) return pyval
def testInPlaceLookupExternalClasses(self): src1 = textwrap.dedent(""" def f1() -> bar.Bar class Foo(object): pass """) src2 = textwrap.dedent(""" def f2() -> foo.Foo class Bar(object): pass """) ast1 = self.Parse(src1, name="foo") ast2 = self.Parse(src2, name="bar") ast1 = ast1.Visit(visitors.LookupExternalTypes(dict(foo=ast1, bar=ast2))) ast2 = ast2.Visit(visitors.LookupExternalTypes(dict(foo=ast1, bar=ast2))) f1, = ast1.Lookup("foo.f1").signatures f2, = ast2.Lookup("bar.f2").signatures self.assertIs(ast2.Lookup("bar.Bar"), f1.return_type.cls) self.assertIs(ast1.Lookup("foo.Foo"), f2.return_type.cls)
def ParseWithBuiltins(self, src): ast = parser.parse_string(textwrap.dedent(src), options=self.options) ast = ast.Visit(visitors.LookupExternalTypes( {"builtins": self.loader.builtins, "typing": self.loader.typing})) ast = ast.Visit(visitors.NamedTypeToClassType()) ast = ast.Visit(visitors.AdjustTypeParameters()) ast.Visit(visitors.FillInLocalPointers({ "": ast, "builtins": self.loader.builtins})) ast.Visit(visitors.VerifyVisitor()) return ast
def ParseWithBuiltins(self, src): ast = parser.parse_string(textwrap.dedent(src), python_version=self.PYTHON_VERSION) ast = ast.Visit(visitors.LookupExternalTypes( {"__builtin__": self.loader.builtins, "typing": self.loader.typing})) ast = ast.Visit(visitors.NamedTypeToClassType()) ast = ast.Visit(visitors.AdjustTypeParameters()) ast.Visit(visitors.FillInLocalPointers({ "": ast, "__builtin__": self.loader.builtins})) ast.Visit(visitors.VerifyVisitor()) return ast
def testLookupStarAliasWithDifferentGetAttr(self): src1 = "def __getattr__(name) -> int" src2 = textwrap.dedent(""" from foo import * def __getattr__(name) -> str """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2}, self_name="bar")) self.assertMultiLineEqual(pytd.Print(ast2), textwrap.dedent("""\ def bar.__getattr__(name) -> str: ..."""))
def testLookupTwoStarAliasesWithSameClass(self): src1 = "class A(object): ..." src2 = "class A(object): ..." src3 = textwrap.dedent(""" from foo import * from bar import * """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast3 = self.Parse(src3).Replace(name="baz").Visit(visitors.AddNamePrefix()) self.assertRaises(KeyError, ast3.Visit, visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2, "baz": ast3}, self_name="baz"))
def testLookupTwoStarAliasesWithDifferentGetAttrs(self): src1 = "def __getattr__(name) -> int" src2 = "def __getattr__(name) -> str" src3 = textwrap.dedent(""" from foo import * from bar import * """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast3 = self.Parse(src3).Replace(name="baz").Visit(visitors.AddNamePrefix()) self.assertRaises(KeyError, ast3.Visit, visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2, "baz": ast3}, self_name="baz"))
def test_lookup_two_star_aliases_with_same_class(self): src1 = "class A: ..." src2 = "class A: ..." src3 = textwrap.dedent(""" from foo import * from bar import * """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast3 = self.Parse(src3).Replace(name="baz").Visit(visitors.AddNamePrefix()) self.assertRaises(KeyError, ast3.Visit, visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2, "baz": ast3}, self_name="baz"))
def _LookupClassReferences(serializable_ast, module_map, self_name): """Fills .cls references in serializable_ast.ast with ones from module_map. Already filled references are not changed. References to the module self._name are not filled. Setting self_name=None will fill all references. Args: serializable_ast: A SerializableAst instance. module_map: Used to resolve ClassType.cls links to already loaded modules. The loaded module will be added to the dict. self_name: A string representation of a module which should not be resolved, for example: "foo.bar.module1" or None to resolve all modules. Returns: A SerializableAst with an updated .ast. .class_type_nodes is set to None if any of the Nodes needed to be regenerated. """ class_lookup = visitors.LookupExternalTypes(module_map, full_names=True, self_name=self_name) raw_ast = serializable_ast.ast for node in (serializable_ast.class_type_nodes or ()): try: if node is not class_lookup.VisitClassType(node): serializable_ast = serializable_ast.Replace( class_type_nodes=None) break except KeyError as e: raise UnrestorableDependencyError("Unresolved class: %r." % e.message) for node in (serializable_ast.function_type_nodes or ()): try: # Use VisitNamedType, even though this is a FunctionType. We want to # do a name lookup, to make sure this is still a function. if not isinstance(class_lookup.VisitNamedType(node), pytd.FunctionType): serializable_ast = serializable_ast.Replace( function_type_nodes=None) break except KeyError as e: raise UnrestorableDependencyError("Unresolved class: %r." % e.message) if (serializable_ast.class_type_nodes is None or serializable_ast.function_type_nodes is None): try: raw_ast = raw_ast.Visit(class_lookup) except KeyError as e: raise UnrestorableDependencyError("Unresolved class: %r." % e.message) serializable_ast = serializable_ast.Replace(ast=raw_ast) return serializable_ast
def test_lookup_star_alias_in_unnamed_module(self): src1 = textwrap.dedent(""" class A: ... """) src2 = "from foo import *" ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2) name = ast2.name ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1}, self_name=None)) self.assertEqual(name, ast2.name) self.assertEqual(pytd_utils.Print(ast2), "from foo import A")
def testLookupConstant(self): src1 = textwrap.dedent(""" Foo = ... # type: type """) src2 = textwrap.dedent(""" class Bar(object): bar = ... # type: foo.Foo """) ast1 = self.Parse(src1, name="foo") ast2 = self.Parse(src2, name="bar") ast2 = ast2.Visit(visitors.LookupExternalTypes({"foo": ast1, "bar": ast2})) self.assertEqual(ast2.Lookup("bar.Bar").constants[0], pytd.Constant(name="bar", type=pytd.AnythingType()))
def test_lookup_star_alias_with_different_getattr(self): src1 = "def __getattr__(name) -> int: ..." src2 = textwrap.dedent(""" from foo import * def __getattr__(name) -> str: ... """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2}, self_name="bar")) self.assertMultiLineEqual(pytd_utils.Print(ast2), textwrap.dedent(""" def bar.__getattr__(name) -> str: ... """).strip())
def testLookupTwoStarAliases(self): src1 = "class A(object): ..." src2 = "class B(object): ..." src3 = textwrap.dedent(""" from foo import * from bar import * """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast3 = self.Parse(src3).Replace(name="baz").Visit(visitors.AddNamePrefix()) ast3 = ast3.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2, "baz": ast3}, self_name="baz")) self.assertSetEqual({a.name for a in ast3.aliases}, {"baz.A", "baz.B"})
def resolve_external_types(self, mod_ast, module_map, aliases, *, mod_name=None): name = mod_name or mod_ast.name try: mod_ast = mod_ast.Visit( visitors.LookupExternalTypes(module_map, self_name=name, module_alias_map=aliases)) except KeyError as e: raise BadDependencyError(utils.message(e), name) from e return mod_ast
def testLookupStarAliasWithDuplicateClass(self): src1 = "class A(object): ..." src2 = textwrap.dedent(""" from foo import * class A(object): x = ... # type: int """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2}, self_name="bar")) self.assertMultiLineEqual(pytd.Print(ast2), textwrap.dedent(""" class bar.A(object): x: int """).strip())
def testLookupStarAliasInUnnamedModule(self): src1 = textwrap.dedent(""" class A(object): ... """) src2 = "from foo import *" ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2) name = ast2.name ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1}, self_name=None)) self.assertEqual(name, ast2.name) self.assertMultiLineEqual(pytd.Print(ast2), textwrap.dedent("""\ import foo A = foo.A"""))
def test_lookup_star_alias_with_duplicate_class(self): src1 = "class A: ..." src2 = textwrap.dedent(""" from foo import * class A: x = ... # type: int """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2}, self_name="bar")) self.assertMultiLineEqual(pytd_utils.Print(ast2), textwrap.dedent(""" class bar.A: x: int """).strip())
def testLookupTwoStarAliasesWithDefaultPyi(self): src1 = "def __getattr__(name) -> ?" src2 = "def __getattr__(name) -> ?" src3 = textwrap.dedent(""" from foo import * from bar import * """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast3 = self.Parse(src3).Replace(name="baz").Visit(visitors.AddNamePrefix()) ast3 = ast3.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2, "baz": ast3}, self_name="baz")) self.assertMultiLineEqual(pytd.Print(ast3), textwrap.dedent("""\ from typing import Any def baz.__getattr__(name) -> Any: ..."""))
def testLookupStarAlias(self): src1 = textwrap.dedent(""" x = ... # type: int T = TypeVar("T") class A(object): ... def f(x: T) -> T: ... B = A """) src2 = "from foo import *" ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast2 = ast2.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2}, self_name="bar")) self.assertEqual("bar", ast2.name) self.assertSetEqual({a.name for a in ast2.aliases}, {"bar.x", "bar.T", "bar.A", "bar.f", "bar.B"})
def test_lookup_two_star_aliases_with_default_pyi(self): src1 = DEFAULT_PYI src2 = DEFAULT_PYI src3 = textwrap.dedent(""" from foo import * from bar import * """) ast1 = self.Parse(src1).Replace(name="foo").Visit(visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit(visitors.AddNamePrefix()) ast3 = self.Parse(src3).Replace(name="baz").Visit(visitors.AddNamePrefix()) ast3 = ast3.Visit(visitors.LookupExternalTypes( {"foo": ast1, "bar": ast2, "baz": ast3}, self_name="baz")) self.assertMultiLineEqual(pytd_utils.Print(ast3), textwrap.dedent(""" from typing import Any def baz.__getattr__(name) -> Any: ... """).strip())
def GetBuiltinsAndTyping(python_version): # Deprecated. Use load_pytd instead. """Get __builtin__.pytd and typing.pytd.""" assert python_version global _cached_builtins_pytd if _cached_builtins_pytd.cache: assert _cached_builtins_pytd.version == python_version else: t = parser.parse_string(_FindBuiltinFile("typing", python_version), name="typing", python_version=python_version) b = parser.parse_string(_FindBuiltinFile("__builtin__", python_version), name="__builtin__", python_version=python_version) b = b.Visit( visitors.LookupExternalTypes({"typing": t}, full_names=True, self_name="__builtin__")) t = t.Visit(visitors.LookupBuiltins(b)) b = b.Visit(visitors.NamedTypeToClassType()) t = t.Visit(visitors.NamedTypeToClassType()) b = b.Visit(visitors.AdjustTypeParameters()) t = t.Visit(visitors.AdjustTypeParameters()) b = b.Visit(visitors.CanonicalOrderingVisitor()) t = t.Visit(visitors.CanonicalOrderingVisitor()) b.Visit( visitors.FillInLocalPointers({ "": b, "typing": t, "__builtin__": b })) t.Visit( visitors.FillInLocalPointers({ "": t, "typing": t, "__builtin__": b })) b.Visit(visitors.VerifyLookup()) t.Visit(visitors.VerifyLookup()) b.Visit(visitors.VerifyContainers()) t.Visit(visitors.VerifyContainers()) _cached_builtins_pytd = Cache(python_version, (b, t)) return _cached_builtins_pytd.cache
def testLookupStarAliasWithDuplicateGetAttr(self): src1 = "def __getattr__(name) -> ?" src2 = textwrap.dedent(""" from foo import * def __getattr__(name) -> ? """) ast1 = self.Parse(src1).Replace(name="foo").Visit( visitors.AddNamePrefix()) ast2 = self.Parse(src2).Replace(name="bar").Visit( visitors.AddNamePrefix()) ast2 = ast2.Visit( visitors.LookupExternalTypes({ "foo": ast1, "bar": ast2 }, self_name="bar")) self.assertMultiLineEqual( pytd_utils.Print(ast2), textwrap.dedent(""" from typing import Any def bar.__getattr__(name) -> Any: ... """).strip())
def GetBuiltinsAndTyping(python_version): # Deprecated. Use load_pytd instead. """Get builtins.pytd and typing.pytd.""" assert python_version if python_version not in _cached_builtins_pytd: t = parser.parse_string(_FindBuiltinFile("typing", python_version), name="typing", python_version=python_version) b = parser.parse_string(_FindBuiltinFile("builtins", python_version), name="builtins", python_version=python_version) b = b.Visit( visitors.LookupExternalTypes({"typing": t}, self_name="builtins")) t = t.Visit(visitors.LookupBuiltins(b)) b = b.Visit(visitors.NamedTypeToClassType()) t = t.Visit(visitors.NamedTypeToClassType()) b = b.Visit(visitors.AdjustTypeParameters()) t = t.Visit(visitors.AdjustTypeParameters()) b = b.Visit(visitors.CanonicalOrderingVisitor()) t = t.Visit(visitors.CanonicalOrderingVisitor()) b.Visit( visitors.FillInLocalPointers({ "": b, "typing": t, "builtins": b })) t.Visit( visitors.FillInLocalPointers({ "": t, "typing": t, "builtins": b })) b.Visit(visitors.VerifyLookup()) t.Visit(visitors.VerifyLookup()) b.Visit(visitors.VerifyContainers()) t.Visit(visitors.VerifyContainers()) _cached_builtins_pytd[python_version] = (b, t) return _cached_builtins_pytd[python_version]