def _verify_pyi(self, pyval, ast_name=None): try: pyval.Visit(visitors.VerifyLookup(ignore_late_types=True)) except ValueError as e: raise BadDependencyError(utils.message(e), ast_name or pyval.name) from e pyval.Visit(visitors.VerifyContainers())
def testVerifyContainerWithMROError(self): # Make sure we don't crash. ast = self.ParseWithBuiltins(""" from typing import List class A(List[str]): ... class B(List[str], A): ... """) ast.Visit(visitors.VerifyContainers())
def testTypeVarValueNoConflict(self): # Not an error if the containers are unrelated, even if they use the same # type parameter name. ast = self.ParseWithBuiltins(""" from typing import ContextManager, SupportsAbs class Foo(SupportsAbs[float], ContextManager[Foo]): ... """) ast.Visit(visitors.VerifyContainers())
def testTypeVarValueConflictRelatedContainers(self): # List inherits from Sequence, so they share a type parameter. ast = self.ParseWithBuiltins(""" from typing import List, Sequence class A(List[int], Sequence[str]): ... """) self.assertRaises(visitors.ContainerError, lambda: ast.Visit(visitors.VerifyContainers()))
def testTypeVarValueConflict(self): # Conflicting values for _T. ast = self.ParseWithBuiltins(""" from typing import List class A(List[int], List[str]): ... """) self.assertRaises(visitors.ContainerError, lambda: ast.Visit(visitors.VerifyContainers()))
def testTypeVarAliasAndValueConflict(self): ast = self.ParseWithBuiltins(""" from typing import Generic, TypeVar T = TypeVar("T") class A(Generic[T]): ... class B(A[T], A[int]): ... """) self.assertRaises(visitors.ContainerError, lambda: ast.Visit(visitors.VerifyContainers()))
def test_typevar_value_conflict_hidden(self): # Conflicting value for _T hidden in MRO. ast = self.ParseWithBuiltins(""" from typing import List class A(List[int]): ... class B(A, List[str]): ... """) self.assertRaises(visitors.ContainerError, lambda: ast.Visit(visitors.VerifyContainers()))
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 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 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]
def testTypeVarValueConsistency(self): # Type renaming makes all type parameters represent the same type `T1`. ast = self.ParseWithBuiltins(""" from typing import Generic, TypeVar T1 = TypeVar("T1") T2 = TypeVar("T2") T3 = TypeVar("T3") T4 = TypeVar("T4") T5 = TypeVar("T5") class A(Generic[T1]): ... class B1(A[T2]): ... class B2(A[T3]): ... class C(B1[T4], B2[T5]): ... class D(C[str, str], A[str]): ... """) ast.Visit(visitors.VerifyContainers())
def testTypeVarValueNoConflictAmbiguousAlias(self): # No conflict due to T1 being aliased to two different type parameters. ast = self.ParseWithBuiltins(""" from typing import Generic, TypeVar T1 = TypeVar("T1") T2 = TypeVar("T2") T3 = TypeVar("T3") T4 = TypeVar("T4") T5 = TypeVar("T5") class A(Generic[T1]): ... class B1(A[T2]): ... class B2(A[T3]): ... class C(B1[T4], B2[T5]): ... class D(C[int, str], A[str]): ... """) ast.Visit(visitors.VerifyContainers())
def _verify_ast(self, ast): try: ast.Visit(visitors.VerifyLookup(ignore_late_types=True)) except ValueError as e: raise BadDependencyError(utils.message(e), ast.name) ast.Visit(visitors.VerifyContainers())