| [case testPEP695TypeAliasBasic] | |
| type MyInt = int | |
| def f(x: MyInt) -> MyInt: | |
| return reveal_type(x) # N: Revealed type is "builtins.int" | |
| type MyList[T] = list[T] | |
| def g(x: MyList[int]) -> MyList[int]: | |
| return reveal_type(x) # N: Revealed type is "builtins.list[builtins.int]" | |
| type MyInt2 = int | |
| def h(x: MyInt2) -> MyInt2: | |
| return reveal_type(x) # N: Revealed type is "builtins.int" | |
| [case testPEP695Class] | |
| class MyGen[T]: | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| def f(x: MyGen[int]): | |
| reveal_type(x.x) # N: Revealed type is "builtins.int" | |
| [case testPEP695Function] | |
| def f[T](x: T) -> T: | |
| return reveal_type(x) # N: Revealed type is "T`-1" | |
| reveal_type(f(1)) # N: Revealed type is "builtins.int" | |
| async def g[T](x: T) -> T: | |
| return reveal_type(x) # N: Revealed type is "T`-1" | |
| reveal_type(g(1)) # E: Value of type "Coroutine[Any, Any, int]" must be used \ | |
| # N: Are you missing an await? \ | |
| # N: Revealed type is "typing.Coroutine[Any, Any, builtins.int]" | |
| [case testPEP695TypeVarBasic] | |
| from typing import Callable | |
| type Alias1[T: int] = list[T] | |
| type Alias2[**P] = Callable[P, int] | |
| type Alias3[*Ts] = tuple[*Ts] | |
| class Cls1[T: int]: ... | |
| class Cls2[**P]: ... | |
| class Cls3[*Ts]: ... | |
| def func1[T: int](x: T) -> T: ... | |
| def func2[**P](x: Callable[P, int]) -> Callable[P, str]: ... | |
| def func3[*Ts](x: tuple[*Ts]) -> tuple[int, *Ts]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695TypeAliasType] | |
| from typing import Callable, TypeAliasType, TypeVar, TypeVarTuple | |
| T = TypeVar("T") | |
| Ts = TypeVarTuple("Ts") | |
| TestType = TypeAliasType("TestType", int | str) | |
| x: TestType = 42 | |
| y: TestType = 'a' | |
| z: TestType = object() # E: Incompatible types in assignment (expression has type "object", variable has type "int | str") | |
| BadAlias1 = TypeAliasType("BadAlias1", tuple[*Ts]) # E: TypeVarTuple "Ts" is not included in type_params | |
| ba1: BadAlias1[int] # E: Bad number of arguments for type alias, expected 0, given 1 | |
| reveal_type(ba1) # N: Revealed type is "builtins.tuple[Any, ...]" | |
| BadAlias2 = TypeAliasType("BadAlias2", Callable[[*Ts], str]) # E: TypeVarTuple "Ts" is not included in type_params | |
| ba2: BadAlias2[int] # E: Bad number of arguments for type alias, expected 0, given 1 | |
| reveal_type(ba2) # N: Revealed type is "def (*Any) -> builtins.str" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695IncompleteFeatureIsAcceptedButHasNoEffect] | |
| # mypy: enable-incomplete-feature=NewGenericSyntax | |
| def f[T](x: T) -> T: | |
| return x | |
| reveal_type(f(1)) # N: Revealed type is "builtins.int" | |
| [case testPEP695GenericFunctionSyntax] | |
| def ident[TV](x: TV) -> TV: | |
| y: TV = x | |
| y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "TV") | |
| return x | |
| reveal_type(ident(1)) # N: Revealed type is "builtins.int" | |
| reveal_type(ident('x')) # N: Revealed type is "builtins.str" | |
| a: TV # E: Name "TV" is not defined | |
| def tup[T, S](x: T, y: S) -> tuple[T, S]: | |
| reveal_type((x, y)) # N: Revealed type is "tuple[T`-1, S`-2]" | |
| return (x, y) | |
| reveal_type(tup(1, 'x')) # N: Revealed type is "tuple[builtins.int, builtins.str]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695GenericClassSyntax] | |
| class C[T]: | |
| x: T | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| def ident(self, x: T) -> T: | |
| y: T = x | |
| if int(): | |
| return self.x | |
| else: | |
| return y | |
| reveal_type(C("x")) # N: Revealed type is "__main__.C[builtins.str]" | |
| c: C[int] = C(1) | |
| reveal_type(c.x) # N: Revealed type is "builtins.int" | |
| reveal_type(c.ident(1)) # N: Revealed type is "builtins.int" | |
| [case testPEP695GenericMethodInGenericClass] | |
| class C[T]: | |
| def m[S](self, x: S) -> T | S: ... | |
| a: C[int] = C[object]() # E: Incompatible types in assignment (expression has type "C[object]", variable has type "C[int]") | |
| b: C[object] = C[int]() | |
| reveal_type(C[str]().m(1)) # N: Revealed type is "builtins.str | builtins.int" | |
| [case testPEP695InferVarianceSimpleFromMethod] | |
| class Invariant[T]: | |
| def f(self, x: T) -> None: | |
| pass | |
| def g(self) -> T | None: | |
| return None | |
| a: Invariant[object] | |
| b: Invariant[int] | |
| if int(): | |
| a = b # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") | |
| class Covariant[T]: | |
| def g(self) -> T | None: | |
| return None | |
| c: Covariant[object] | |
| d: Covariant[int] | |
| if int(): | |
| c = d | |
| if int(): | |
| d = c # E: Incompatible types in assignment (expression has type "Covariant[object]", variable has type "Covariant[int]") | |
| class Contravariant[T]: | |
| def f(self, x: T) -> None: | |
| pass | |
| e: Contravariant[object] | |
| f: Contravariant[int] | |
| if int(): | |
| e = f # E: Incompatible types in assignment (expression has type "Contravariant[int]", variable has type "Contravariant[object]") | |
| if int(): | |
| f = e | |
| [case testPEP695InferVarianceSimpleFromAttribute] | |
| class Invariant1[T]: | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| a: Invariant1[object] | |
| b: Invariant1[int] | |
| if int(): | |
| a = b # E: Incompatible types in assignment (expression has type "Invariant1[int]", variable has type "Invariant1[object]") | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "Invariant1[object]", variable has type "Invariant1[int]") | |
| class Invariant2[T]: | |
| def __init__(self) -> None: | |
| self.x: list[T] = [] | |
| a2: Invariant2[object] | |
| b2: Invariant2[int] | |
| if int(): | |
| a2 = b2 # E: Incompatible types in assignment (expression has type "Invariant2[int]", variable has type "Invariant2[object]") | |
| if int(): | |
| b2 = a2 # E: Incompatible types in assignment (expression has type "Invariant2[object]", variable has type "Invariant2[int]") | |
| class Invariant3[T]: | |
| def __init__(self) -> None: | |
| self.x: T | None = None | |
| a3: Invariant3[object] | |
| b3: Invariant3[int] | |
| if int(): | |
| a3 = b3 # E: Incompatible types in assignment (expression has type "Invariant3[int]", variable has type "Invariant3[object]") | |
| if int(): | |
| b3 = a3 # E: Incompatible types in assignment (expression has type "Invariant3[object]", variable has type "Invariant3[int]") | |
| [case testPEP695InferVarianceRecursive] | |
| class Invariant[T]: | |
| def f(self, x: Invariant[T]) -> Invariant[T]: | |
| return x | |
| class Covariant[T]: | |
| def f(self) -> Covariant[T]: | |
| return self | |
| class Contravariant[T]: | |
| def f(self, x: Contravariant[T]) -> None: | |
| pass | |
| a: Invariant[object] | |
| b: Invariant[int] | |
| if int(): | |
| a = b # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") | |
| if int(): | |
| b = a | |
| c: Covariant[object] | |
| d: Covariant[int] | |
| if int(): | |
| c = d | |
| if int(): | |
| d = c # E: Incompatible types in assignment (expression has type "Covariant[object]", variable has type "Covariant[int]") | |
| e: Contravariant[object] | |
| f: Contravariant[int] | |
| if int(): | |
| e = f # E: Incompatible types in assignment (expression has type "Contravariant[int]", variable has type "Contravariant[object]") | |
| if int(): | |
| f = e | |
| [case testPEP695InferVarianceInFrozenDataclass] | |
| from dataclasses import dataclass | |
| @dataclass(frozen=True) | |
| class Covariant[T]: | |
| x: T | |
| cov1: Covariant[float] = Covariant[int](1) | |
| cov2: Covariant[int] = Covariant[float](1) # E: Incompatible types in assignment (expression has type "Covariant[float]", variable has type "Covariant[int]") | |
| @dataclass(frozen=True) | |
| class Invariant[T]: | |
| x: list[T] | |
| inv1: Invariant[float] = Invariant[int]([1]) # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[float]") | |
| inv2: Invariant[int] = Invariant[float]([1]) # E: Incompatible types in assignment (expression has type "Invariant[float]", variable has type "Invariant[int]") | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695InferVarianceCalculateOnDemand] | |
| class Covariant[T]: | |
| def __init__(self) -> None: | |
| self.x = [1] | |
| def f(self) -> None: | |
| c = Covariant[int]() | |
| # We need to know that T is covariant here | |
| self.g(c) | |
| c2 = Covariant[object]() | |
| self.h(c2) # E: Argument 1 to "h" of "Covariant" has incompatible type "Covariant[object]"; expected "Covariant[int]" | |
| def g(self, x: Covariant[object]) -> None: pass | |
| def h(self, x: Covariant[int]) -> None: pass | |
| [case testPEP695InferVarianceNotReadyWhenNeeded] | |
| class Covariant[T]: | |
| def f(self) -> None: | |
| c = Covariant[int]() | |
| # We need to know that T is covariant here | |
| self.g(c) | |
| c2 = Covariant[object]() | |
| self.h(c2) # E: Argument 1 to "h" of "Covariant" has incompatible type "Covariant[object]"; expected "Covariant[int]" | |
| def g(self, x: Covariant[object]) -> None: pass | |
| def h(self, x: Covariant[int]) -> None: pass | |
| def __init__(self) -> None: | |
| self.x = [1] | |
| class Invariant[T]: | |
| def f(self) -> None: | |
| # We add this to force processing this method as part of the interface in parallel checking, | |
| # otherwise, it will be processed at a later stage, not testing the no ready behavior below | |
| self.y = int() | |
| c = Invariant(1) | |
| # We need to know that T is invariant here, and for this we need the type | |
| # of self.x, which won't be available on the first type checking pass, | |
| # since __init__ is defined later in the file. In this case we fall back | |
| # covariance. | |
| self.g(c) | |
| c2 = Invariant(object()) | |
| self.h(c2) # E: Argument 1 to "h" of "Invariant" has incompatible type "Invariant[object]"; expected "Invariant[int]" | |
| def g(self, x: Invariant[object]) -> None: pass | |
| def h(self, x: Invariant[int]) -> None: pass | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| # Now we should have the variance correct. | |
| a: Invariant[object] | |
| b: Invariant[int] | |
| if int(): | |
| a = b # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") | |
| [case testPEP695InferVarianceNotReadyForJoin] | |
| class Invariant[T]: | |
| def f(self) -> None: | |
| self.y = int() | |
| # Assume covariance if variance us not ready | |
| reveal_type([Invariant(1), Invariant(object())]) \ | |
| # N: Revealed type is "builtins.list[__main__.Invariant[builtins.object]]" | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| reveal_type([Invariant(1), Invariant(object())]) # N: Revealed type is "builtins.list[builtins.object]" | |
| [case testPEP695InferVarianceNotReadyForMeet] | |
| from typing import TypeVar, Callable | |
| S = TypeVar("S") | |
| def c(a: Callable[[S], None], b: Callable[[S], None]) -> S: ... | |
| def a1(x: Invariant[int]) -> None: pass | |
| def a2(x: Invariant[object]) -> None: pass | |
| class Invariant[T]: | |
| def f(self) -> None: | |
| self.y = int() | |
| reveal_type(c(a1, a2)) # N: Revealed type is "__main__.Invariant[builtins.int]" | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| reveal_type(c(a1, a2)) # N: Revealed type is "Never" | |
| [case testPEP695InferVarianceUnderscorePrefix] | |
| class Covariant1[T]: | |
| def __init__(self, x: T) -> None: | |
| self._x = x | |
| @property | |
| def x(self) -> T: | |
| return self._x | |
| co1_1: Covariant1[float] = Covariant1[int](1) | |
| co1_2: Covariant1[int] = Covariant1[float](1) # E: Incompatible types in assignment (expression has type "Covariant1[float]", variable has type "Covariant1[int]") | |
| class Covariant2[T]: | |
| def __init__(self, x: T) -> None: | |
| self.__foo_bar = x | |
| @property | |
| def x(self) -> T: | |
| return self.__foo_bar | |
| co2_1: Covariant2[float] = Covariant2[int](1) | |
| co2_2: Covariant2[int] = Covariant2[float](1) # E: Incompatible types in assignment (expression has type "Covariant2[float]", variable has type "Covariant2[int]") | |
| class Invariant1[T]: | |
| def __init__(self, x: T) -> None: | |
| self._x = x | |
| # Methods behave differently from attributes | |
| def _f(self, x: T) -> None: ... | |
| @property | |
| def x(self) -> T: | |
| return self._x | |
| inv1_1: Invariant1[float] = Invariant1[int](1) # E: Incompatible types in assignment (expression has type "Invariant1[int]", variable has type "Invariant1[float]") | |
| inv1_2: Invariant1[int] = Invariant1[float](1) # E: Incompatible types in assignment (expression has type "Invariant1[float]", variable has type "Invariant1[int]") | |
| class Invariant2[T]: | |
| def __init__(self, x: T) -> None: | |
| # Dunders are special | |
| self.__x__ = x | |
| @property | |
| def x(self) -> T: | |
| return self.__x__ | |
| inv2_1: Invariant2[float] = Invariant2[int](1) # E: Incompatible types in assignment (expression has type "Invariant2[int]", variable has type "Invariant2[float]") | |
| inv2_2: Invariant2[int] = Invariant2[float](1) # E: Incompatible types in assignment (expression has type "Invariant2[float]", variable has type "Invariant2[int]") | |
| class Invariant3[T]: | |
| def __init__(self, x: T) -> None: | |
| self._x = Invariant1(x) | |
| @property | |
| def x(self) -> T: | |
| return self._x._x | |
| inv3_1: Invariant3[float] = Invariant3[int](1) # E: Incompatible types in assignment (expression has type "Invariant3[int]", variable has type "Invariant3[float]") | |
| inv3_2: Invariant3[int] = Invariant3[float](1) # E: Incompatible types in assignment (expression has type "Invariant3[float]", variable has type "Invariant3[int]") | |
| [builtins fixtures/property.pyi] | |
| [case testPEP695InferVarianceWithInheritedSelf] | |
| from typing import overload, Self, TypeVar, Generic | |
| T = TypeVar("T") | |
| S = TypeVar("S") | |
| class C(Generic[T]): | |
| def f(self, x: T) -> Self: ... | |
| def g(self) -> T: ... | |
| class D[T1, T2](C[T1]): | |
| def m(self, x: T2) -> None: ... | |
| a1: D[int, int] = D[int, object]() | |
| a2: D[int, object] = D[int, int]() # E: Incompatible types in assignment (expression has type "D[int, int]", variable has type "D[int, object]") | |
| a3: D[int, int] = D[object, object]() # E: Incompatible types in assignment (expression has type "D[object, object]", variable has type "D[int, int]") | |
| a4: D[object, int] = D[int, object]() # E: Incompatible types in assignment (expression has type "D[int, object]", variable has type "D[object, int]") | |
| [case testPEP695InferVarianceWithReturnSelf] | |
| from typing import Self, overload | |
| class Cov[T]: | |
| def f(self) -> Self: ... | |
| a1: Cov[int] = Cov[float]() # E: Incompatible types in assignment (expression has type "Cov[float]", variable has type "Cov[int]") | |
| a2: Cov[float] = Cov[int]() | |
| class Contra[T]: | |
| def f(self) -> Self: ... | |
| def g(self, x: T) -> None: ... | |
| b1: Contra[int] = Contra[float]() | |
| b2: Contra[float] = Contra[int]() # E: Incompatible types in assignment (expression has type "Contra[int]", variable has type "Contra[float]") | |
| class Cov2[T]: | |
| @overload | |
| def f(self, x): ... | |
| @overload | |
| def f(self) -> Self: ... | |
| def f(self, x=None): ... | |
| c1: Cov2[int] = Cov2[float]() # E: Incompatible types in assignment (expression has type "Cov2[float]", variable has type "Cov2[int]") | |
| c2: Cov2[float] = Cov2[int]() | |
| class Contra2[T]: | |
| @overload | |
| def f(self, x): ... | |
| @overload | |
| def f(self) -> Self: ... | |
| def f(self, x=None): ... | |
| def g(self, x: T) -> None: ... | |
| d1: Contra2[int] = Contra2[float]() | |
| d2: Contra2[float] = Contra2[int]() # E: Incompatible types in assignment (expression has type "Contra2[int]", variable has type "Contra2[float]") | |
| [case testPEP695InheritInvariant] | |
| class Invariant[T]: | |
| x: T | |
| class Subclass[T](Invariant[T]): | |
| pass | |
| x: Invariant[int] | |
| y: Invariant[object] | |
| if int(): | |
| x = y # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") | |
| if int(): | |
| y = x # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") | |
| a: Subclass[int] | |
| b: Subclass[object] | |
| if int(): | |
| a = b # E: Incompatible types in assignment (expression has type "Subclass[object]", variable has type "Subclass[int]") | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "Subclass[int]", variable has type "Subclass[object]") | |
| [case testPEP695InheritanceMakesInvariant] | |
| class Covariant[T]: | |
| def f(self) -> T: | |
| ... | |
| class Subclass[T](Covariant[list[T]]): | |
| pass | |
| x: Covariant[int] = Covariant[object]() # E: Incompatible types in assignment (expression has type "Covariant[object]", variable has type "Covariant[int]") | |
| y: Covariant[object] = Covariant[int]() | |
| a: Subclass[int] = Subclass[object]() # E: Incompatible types in assignment (expression has type "Subclass[object]", variable has type "Subclass[int]") | |
| b: Subclass[object] = Subclass[int]() # E: Incompatible types in assignment (expression has type "Subclass[int]", variable has type "Subclass[object]") | |
| [case testPEP695InheritCoOrContravariant] | |
| class Contravariant[T]: | |
| def f(self, x: T) -> None: pass | |
| class CovSubclass[T](Contravariant[T]): | |
| pass | |
| a: CovSubclass[int] = CovSubclass[object]() | |
| b: CovSubclass[object] = CovSubclass[int]() # E: Incompatible types in assignment (expression has type "CovSubclass[int]", variable has type "CovSubclass[object]") | |
| class Covariant[T]: | |
| def f(self) -> T: ... | |
| class CoSubclass[T](Covariant[T]): | |
| pass | |
| c: CoSubclass[int] = CoSubclass[object]() # E: Incompatible types in assignment (expression has type "CoSubclass[object]", variable has type "CoSubclass[int]") | |
| d: CoSubclass[object] = CoSubclass[int]() | |
| class InvSubclass[T](Covariant[T]): | |
| def g(self, x: T) -> None: pass | |
| e: InvSubclass[int] = InvSubclass[object]() # E: Incompatible types in assignment (expression has type "InvSubclass[object]", variable has type "InvSubclass[int]") | |
| f: InvSubclass[object] = InvSubclass[int]() # E: Incompatible types in assignment (expression has type "InvSubclass[int]", variable has type "InvSubclass[object]") | |
| [case testPEP695FinalAttribute] | |
| from typing import Final | |
| class C[T]: | |
| def __init__(self, x: T) -> None: | |
| self.x: Final = x | |
| a: C[int] = C[object](1) # E: Incompatible types in assignment (expression has type "C[object]", variable has type "C[int]") | |
| b: C[object] = C[int](1) | |
| [case testPEP695TwoTypeVariables] | |
| class C[T, S]: | |
| def f(self, x: T) -> None: ... | |
| def g(self) -> S: ... | |
| a: C[int, int] = C[object, int]() | |
| b: C[object, int] = C[int, int]() # E: Incompatible types in assignment (expression has type "C[int, int]", variable has type "C[object, int]") | |
| c: C[int, int] = C[int, object]() # E: Incompatible types in assignment (expression has type "C[int, object]", variable has type "C[int, int]") | |
| d: C[int, object] = C[int, int]() | |
| [case testPEP695Properties] | |
| class R[T]: | |
| @property | |
| def p(self) -> T: ... | |
| class RW[T]: | |
| @property | |
| def p(self) -> T: ... | |
| @p.setter | |
| def p(self, x: T) -> None: ... | |
| a: R[int] = R[object]() # E: Incompatible types in assignment (expression has type "R[object]", variable has type "R[int]") | |
| b: R[object] = R[int]() | |
| c: RW[int] = RW[object]() # E: Incompatible types in assignment (expression has type "RW[object]", variable has type "RW[int]") | |
| d: RW[object] = RW[int]() # E: Incompatible types in assignment (expression has type "RW[int]", variable has type "RW[object]") | |
| [builtins fixtures/property.pyi] | |
| [case testPEP695Protocol] | |
| from typing import Protocol | |
| class PContra[T](Protocol): | |
| def f(self, x: T) -> None: ... | |
| PContra() # E: Cannot instantiate protocol class "PContra" | |
| a: PContra[int] | |
| b: PContra[object] | |
| if int(): | |
| a = b | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "PContra[int]", variable has type "PContra[object]") | |
| class PCov[T](Protocol): | |
| def f(self) -> T: ... | |
| PCov() # E: Cannot instantiate protocol class "PCov" | |
| c: PCov[int] | |
| d: PCov[object] | |
| if int(): | |
| c = d # E: Incompatible types in assignment (expression has type "PCov[object]", variable has type "PCov[int]") | |
| if int(): | |
| d = c | |
| class PInv[T](Protocol): | |
| def f(self, x: T) -> T: ... | |
| PInv() # E: Cannot instantiate protocol class "PInv" | |
| e: PInv[int] | |
| f: PInv[object] | |
| if int(): | |
| e = f # E: Incompatible types in assignment (expression has type "PInv[object]", variable has type "PInv[int]") | |
| if int(): | |
| f = e # E: Incompatible types in assignment (expression has type "PInv[int]", variable has type "PInv[object]") | |
| [case testPEP695TypeAlias] | |
| class C[T]: pass | |
| class D[T, S]: pass | |
| type A[S] = C[S] | |
| a: A[int] | |
| reveal_type(a) # N: Revealed type is "__main__.C[builtins.int]" | |
| type A2[T] = C[C[T]] | |
| a2: A2[str] | |
| reveal_type(a2) # N: Revealed type is "__main__.C[__main__.C[builtins.str]]" | |
| type A3[T, S] = D[S, C[T]] | |
| a3: A3[int, str] | |
| reveal_type(a3) # N: Revealed type is "__main__.D[builtins.str, __main__.C[builtins.int]]" | |
| type A4 = int | str | |
| a4: A4 | |
| reveal_type(a4) # N: Revealed type is "builtins.int | builtins.str" | |
| [builtins fixtures/type.pyi] | |
| [case testPEP695TypeAliasNotValidAsBaseClass] | |
| from typing import TypeAlias | |
| import m | |
| type A1 = int | |
| class Bad1(A1): # E: Type alias defined using "type" statement not valid as base class | |
| pass | |
| type A2[T] = list[T] | |
| class Bad2(A2[int]): # E: Type alias defined using "type" statement not valid as base class | |
| pass | |
| class Bad3(m.A1): # E: Type alias defined using "type" statement not valid as base class | |
| pass | |
| class Bad4(m.A2[int]): # E: Type alias defined using "type" statement not valid as base class | |
| pass | |
| B1 = int | |
| B2 = list | |
| B3: TypeAlias = int | |
| class Good1(B1): pass | |
| class Good2(B2[int]): pass | |
| class Good3(list[A1]): pass | |
| class Good4(list[A2[int]]): pass | |
| class Good5(B3): pass | |
| [file m.py] | |
| type A1 = str | |
| type A2[T] = list[T] | |
| [typing fixtures/typing-medium.pyi] | |
| [case testPEP695TypeAliasWithUnusedTypeParams] | |
| type A[T] = int | |
| a: A[str] | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| [case testPEP695TypeAliasForwardReference1] | |
| type A[T] = C[T] | |
| a: A[int] | |
| reveal_type(a) # N: Revealed type is "__main__.C[builtins.int]" | |
| class C[T]: pass | |
| [case testPEP695TypeAliasForwardReference2] | |
| type X = C | |
| type A = X | |
| a: A | |
| reveal_type(a) # N: Revealed type is "__main__.C" | |
| class C: pass | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasForwardReference3] | |
| type X = D | |
| type A = C[X] | |
| a: A | |
| reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" | |
| class C[T]: pass | |
| class D: pass | |
| [case testPEP695TypeAliasForwardReference4] | |
| type A = C | |
| class D(A): # E: Type alias defined using "type" statement not valid as base class | |
| pass | |
| class C: pass | |
| x: C = D() | |
| y: D = C() # E: Incompatible types in assignment (expression has type "C", variable has type "D") | |
| [case testPEP695TypeAliasForwardReference5] | |
| type A = str | |
| type B[T] = C[T] | |
| class C[T]: pass | |
| a: A | |
| b: B[int] | |
| c: C[str] | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| reveal_type(b) # N: Revealed type is "__main__.C[builtins.int]" | |
| reveal_type(c) # N: Revealed type is "__main__.C[builtins.str]" | |
| [case testPEP695TypeAliasWithUndefineName] | |
| type A[T] = XXX # E: Name "XXX" is not defined | |
| a: A[int] | |
| reveal_type(a) # N: Revealed type is "Any" | |
| [case testPEP695TypeAliasInvalidType] | |
| type A = int | 1 # E: Invalid type: try using Literal[1] instead? | |
| a: A | |
| reveal_type(a) # N: Revealed type is "builtins.int | Any" | |
| type B = int + str # E: Invalid type alias: expression is not a valid type | |
| b: B | |
| reveal_type(b) # N: Revealed type is "Any" | |
| [builtins fixtures/type.pyi] | |
| [case testPEP695TypeAliasBoundForwardReference] | |
| type B[T: Foo] = list[T] | |
| class Foo: pass | |
| [case testPEP695UpperBound] | |
| class D: | |
| x: int | |
| class E(D): pass | |
| class C[T: D]: pass | |
| a: C[D] | |
| b: C[E] | |
| reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" | |
| reveal_type(b) # N: Revealed type is "__main__.C[__main__.E]" | |
| c: C[int] # E: Type argument "int" of "C" must be a subtype of "D" | |
| def f[T: D](a: T) -> T: | |
| reveal_type(a.x) # N: Revealed type is "builtins.int" | |
| return a | |
| reveal_type(f(D())) # N: Revealed type is "__main__.D" | |
| reveal_type(f(E())) # N: Revealed type is "__main__.E" | |
| f(1) # E: Value of type variable "T" of "f" cannot be "int" | |
| [case testPEP695UpperBoundForwardReference1] | |
| class C[T: D]: pass | |
| a: C[D] | |
| b: C[E] | |
| reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" | |
| reveal_type(b) # N: Revealed type is "__main__.C[__main__.E]" | |
| c: C[int] # E: Type argument "int" of "C" must be a subtype of "D" | |
| class D: pass | |
| class E(D): pass | |
| [case testPEP695UpperBoundForwardReference2] | |
| type A = D | |
| class C[T: A]: pass | |
| class D: pass | |
| class E(D): pass | |
| a: C[D] | |
| b: C[E] | |
| reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" | |
| reveal_type(b) # N: Revealed type is "__main__.C[__main__.E]" | |
| c: C[int] # E: Type argument "int" of "C" must be a subtype of "D" | |
| [case testPEP695UpperBoundForwardReference3] | |
| class D[T]: pass | |
| class E[T](D[T]): pass | |
| type A = D[X] | |
| class C[T: A]: pass | |
| class X: pass | |
| a: C[D[X]] | |
| b: C[E[X]] | |
| reveal_type(a) # N: Revealed type is "__main__.C[__main__.D[__main__.X]]" | |
| reveal_type(b) # N: Revealed type is "__main__.C[__main__.E[__main__.X]]" | |
| c: C[D[int]] # E: Type argument "D[int]" of "C" must be a subtype of "D[X]" | |
| [case testPEP695UpperBoundForwardReference4] | |
| def f[T: D](a: T) -> T: | |
| reveal_type(a.x) # N: Revealed type is "builtins.int" | |
| return a | |
| class D: | |
| x: int | |
| class E(D): pass | |
| reveal_type(f(D())) # N: Revealed type is "__main__.D" | |
| reveal_type(f(E())) # N: Revealed type is "__main__.E" | |
| f(1) # E: Value of type variable "T" of "f" cannot be "int" | |
| [case testPEP695UpperBoundUndefinedName] | |
| class C[T: XX]: # E: Name "XX" is not defined | |
| pass | |
| a: C[int] | |
| def f[T: YY](x: T) -> T: # E: Name "YY" is not defined | |
| return x | |
| reveal_type(f) # N: Revealed type is "def [T <: Any] (x: T`-1) -> T`-1" | |
| [case testPEP695UpperBoundWithMultipleParams] | |
| class C[T, S: int]: pass | |
| class D[A: int, B]: pass | |
| def f[T: int, S: int | str](x: T, y: S) -> T | S: | |
| return x | |
| C[str, int]() | |
| C[str, str]() # E: Value of type variable "S" of "C" cannot be "str" | |
| D[int, str]() | |
| D[str, str]() # E: Value of type variable "A" of "D" cannot be "str" | |
| f(1, 1) | |
| u: int | str | |
| f(1, u) | |
| f('x', None) # E: Value of type variable "T" of "f" cannot be "str" \ | |
| # E: Value of type variable "S" of "f" cannot be "None" | |
| [case testPEP695UpperBoundTypeTypeConstructorReturnType] | |
| class A: | |
| def __init__(self, value: str = "") -> None: pass | |
| class B: | |
| def __init__(self, value: str = "") -> None: pass | |
| def make[T: A | B](ftype: type[T], value: str | None) -> T: | |
| if value is None: | |
| return ftype() | |
| return ftype(value) | |
| reveal_type(make(A, "a")) # N: Revealed type is "__main__.A" | |
| reveal_type(make(B, None)) # N: Revealed type is "__main__.B" | |
| [case testPEP695InferVarianceOfTupleType] | |
| class Cov[T](tuple[int, str]): | |
| def f(self) -> T: pass | |
| class Cov2[T](tuple[T, T]): | |
| pass | |
| class Contra[T](tuple[int, str]): | |
| def f(self, x: T) -> None: pass | |
| a: Cov[object] = Cov[int]() | |
| b: Cov[int] = Cov[object]() # E: Incompatible types in assignment (expression has type "Cov[object]", variable has type "Cov[int]") | |
| c: Cov2[object] = Cov2[int]() | |
| d: Cov2[int] = Cov2[object]() # E: Incompatible types in assignment (expression has type "Cov2[object]", variable has type "Cov2[int]") | |
| e: Contra[int] = Contra[object]() | |
| f: Contra[object] = Contra[int]() # E: Incompatible types in assignment (expression has type "Contra[int]", variable has type "Contra[object]") | |
| [builtins fixtures/tuple-simple.pyi] | |
| [case testPEP695ValueRestriction] | |
| def f[T: (int, str)](x: T) -> T: | |
| reveal_type(x) # N: Revealed type is "builtins.int" \ | |
| # N: Revealed type is "builtins.str" | |
| return x | |
| reveal_type(f(1)) # N: Revealed type is "builtins.int" | |
| reveal_type(f('x')) # N: Revealed type is "builtins.str" | |
| f(None) # E: Value of type variable "T" of "f" cannot be "None" | |
| class C[T: (object, None)]: pass | |
| a: C[object] | |
| b: C[None] | |
| c: C[int] # E: Value of type variable "T" of "C" cannot be "int" | |
| [case testPEP695ValueRestrictionForwardReference] | |
| class C[T: (int, D)]: | |
| def __init__(self, x: T) -> None: | |
| a = x | |
| if int(): | |
| a = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") \ | |
| # E: Incompatible types in assignment (expression has type "str", variable has type "D") | |
| self.x: T = x | |
| reveal_type(C(1).x) # N: Revealed type is "builtins.int" | |
| C(None) # E: Value of type variable "T" of "C" cannot be "None" | |
| class D: pass | |
| C(D()) | |
| [case testPEP695ValueRestrictionUndefinedName] | |
| class C[T: (int, XX)]: # E: Name "XX" is not defined | |
| pass | |
| def f[S: (int, YY)](x: S) -> S: # E: Name "YY" is not defined | |
| return x | |
| [case testPEP695ParamSpec] | |
| from typing import Callable | |
| def g[**P](f: Callable[P, None], *args: P.args, **kwargs: P.kwargs) -> None: | |
| f(*args, **kwargs) | |
| f(1, *args, **kwargs) # E: Argument 1 has incompatible type "int"; expected "P.args" | |
| def h(x: int, y: str) -> None: pass | |
| g(h, 1, y='x') | |
| g(h, 1, x=1) # E: "g" gets multiple values for keyword argument "x" \ | |
| # E: Missing positional argument "y" in call to "g" | |
| class C[**P, T]: | |
| def m(self, *args: P.args, **kwargs: P.kwargs) -> T: ... | |
| a: C[[int, str], None] | |
| reveal_type(a) # N: Revealed type is "__main__.C[[builtins.int, builtins.str], None]" | |
| reveal_type(a.m) # N: Revealed type is "def (builtins.int, builtins.str)" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695ParamSpecTypeAlias] | |
| from typing import Callable | |
| type C[**P] = Callable[P, int] | |
| f: C[[str, int | None]] | |
| reveal_type(f) # N: Revealed type is "def (builtins.str, builtins.int | None) -> builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeVarTuple] | |
| def f[*Ts](t: tuple[*Ts]) -> tuple[*Ts]: | |
| reveal_type(t) # N: Revealed type is "tuple[Unpack[Ts`-1]]" | |
| return t | |
| reveal_type(f((1, 'x'))) # N: Revealed type is "tuple[Literal[1]?, Literal['x']?]" | |
| a: tuple[int, ...] | |
| reveal_type(f(a)) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | |
| class C[T, *Ts]: | |
| pass | |
| b: C[int, str, None] | |
| reveal_type(b) # N: Revealed type is "__main__.C[builtins.int, builtins.str, None]" | |
| c: C[str] | |
| reveal_type(c) # N: Revealed type is "__main__.C[builtins.str]" | |
| b = c # E: Incompatible types in assignment (expression has type "C[str]", variable has type "C[int, str, None]") | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695TypeVarTupleAlias] | |
| from typing import Callable | |
| type C[*Ts] = tuple[*Ts, int] | |
| a: C[str, None] | |
| reveal_type(a) # N: Revealed type is "tuple[builtins.str, None, builtins.int]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695IncrementalFunction] | |
| import a | |
| [file a.py] | |
| import b | |
| [file a.py.2] | |
| import b | |
| reveal_type(b.f(1)) | |
| reveal_type(b.g(1, 'x')) | |
| b.g('x', 'x') | |
| b.g(1, 2) | |
| [file b.py] | |
| def f[T](x: T) -> T: | |
| return x | |
| def g[T: int, S: (str, None)](x: T, y: S) -> T | S: | |
| return x | |
| [out2] | |
| tmp/a.py:2: note: Revealed type is "builtins.int" | |
| tmp/a.py:3: note: Revealed type is "builtins.int | builtins.str" | |
| tmp/a.py:4: error: Value of type variable "T" of "g" cannot be "str" | |
| tmp/a.py:5: error: Value of type variable "S" of "g" cannot be "int" | |
| [case testPEP695IncrementalClass] | |
| import a | |
| [file a.py] | |
| import b | |
| [file a.py.2] | |
| from b import C, D | |
| x: C[int] | |
| reveal_type(x) | |
| class N(int): pass | |
| class SS(str): pass | |
| y1: D[int, str] | |
| y2: D[N, str] | |
| y3: D[int, None] | |
| y4: D[int, None] | |
| y5: D[int, SS] # Error | |
| y6: D[object, str] # Error | |
| [file b.py] | |
| class C[T]: pass | |
| class D[T: int, S: (str, None)]: | |
| pass | |
| [out2] | |
| tmp/a.py:3: note: Revealed type is "b.C[builtins.int]" | |
| tmp/a.py:12: error: Value of type variable "S" of "D" cannot be "SS" | |
| tmp/a.py:13: error: Type argument "object" of "D" must be a subtype of "int" | |
| [case testPEP695IncrementalParamSpecAndTypeVarTuple] | |
| import a | |
| [file a.py] | |
| import b | |
| [file a.py.2] | |
| from b import C, D | |
| x1: C[()] | |
| x2: C[int] | |
| x3: C[int, str] | |
| y: D[[int, str]] | |
| reveal_type(y.m) | |
| [file b.py] | |
| class C[*Ts]: pass | |
| class D[**P]: | |
| def m(self, *args: P.args, **kwargs: P.kwargs) -> None: pass | |
| [builtins fixtures/tuple.pyi] | |
| [out2] | |
| tmp/a.py:6: note: Revealed type is "def (builtins.int, builtins.str)" | |
| [case testPEP695IncrementalTypeAlias] | |
| import a | |
| [file a.py] | |
| import b | |
| [file a.py.2] | |
| from b import A, B | |
| a: A | |
| reveal_type(a) | |
| b: B[int] | |
| reveal_type(b) | |
| [file b.py] | |
| type A = str | |
| class Foo[T]: pass | |
| type B[T] = Foo[T] | |
| [builtins fixtures/tuple.pyi] | |
| [out2] | |
| tmp/a.py:3: note: Revealed type is "builtins.str" | |
| tmp/a.py:5: note: Revealed type is "b.Foo[builtins.int]" | |
| [case testPEP695UndefinedNameInGenericFunction] | |
| def f[T](x: T) -> T: | |
| return unknown() # E: Name "unknown" is not defined | |
| class C: | |
| def m[T](self, x: T) -> T: | |
| return unknown() # E: Name "unknown" is not defined | |
| [case testPEP695FunctionTypeVarAccessInFunction] | |
| from typing import cast | |
| class C: | |
| def m[T](self, x: T) -> T: | |
| y: T = x | |
| reveal_type(y) # N: Revealed type is "T`-1" | |
| return cast(T, y) | |
| reveal_type(C().m(1)) # N: Revealed type is "builtins.int" | |
| [case testPEP695ScopingBasics] | |
| T = 1 | |
| def f[T](x: T) -> T: | |
| T = 'a' | |
| reveal_type(T) # N: Revealed type is "builtins.str" | |
| return x | |
| reveal_type(T) # N: Revealed type is "builtins.int" | |
| class C[T]: | |
| T = 1.2 | |
| reveal_type(T) # N: Revealed type is "builtins.float" | |
| reveal_type(T) # N: Revealed type is "builtins.int" | |
| [case testPEP695ClassScoping] | |
| class C: | |
| class D: pass | |
| def m[T: D](self, x: T, y: D) -> T: | |
| return x | |
| C().m(C.D(), C.D()) | |
| C().m(1, C.D()) # E: Value of type variable "T" of "m" of "C" cannot be "int" | |
| [case testPEP695NestedGenericFunction] | |
| def f[T](x: T) -> T: | |
| reveal_type(f(x)) # N: Revealed type is "T`-1" | |
| reveal_type(f(1)) # N: Revealed type is "builtins.int" | |
| def ff(x: T) -> T: | |
| y: T = x | |
| return y | |
| reveal_type(ff(x)) # N: Revealed type is "T`-1" | |
| ff(1) # E: Argument 1 to "ff" has incompatible type "int"; expected "T" | |
| def g[S](a: S) -> S: | |
| ff(a) # E: Argument 1 to "ff" has incompatible type "S"; expected "T" | |
| return a | |
| reveal_type(g(1)) # N: Revealed type is "builtins.int" | |
| reveal_type(g(x)) # N: Revealed type is "T`-1" | |
| def h[S](a: S) -> S: | |
| return a | |
| reveal_type(h(1)) # N: Revealed type is "builtins.int" | |
| reveal_type(h(x)) # N: Revealed type is "T`-1" | |
| return x | |
| [case testPEP695NonLocalAndGlobal] | |
| def f() -> None: | |
| T = 1 | |
| def g[T](x: T) -> T: | |
| nonlocal T # E: nonlocal binding not allowed for type parameter "T" | |
| T = 'x' # E: "T" is a type variable and only valid in type context | |
| return x | |
| reveal_type(T) # N: Revealed type is "builtins.int" | |
| def g() -> None: | |
| a = 1 | |
| def g[T](x: T) -> T: | |
| nonlocal a | |
| a = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| return x | |
| x = 1 | |
| def h[T](a: T) -> T: | |
| global x | |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| return a | |
| class C[T]: | |
| def m[S](self, a: S) -> S: | |
| global x | |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| return a | |
| [case testPEP695ParameterDefault] | |
| from typing import cast | |
| def f[T]( | |
| x: T = | |
| T # E: Name "T" is not defined \ | |
| # E: Incompatible default for parameter "x" (default has type "TypeVar", parameter has type "T") | |
| ) -> T: | |
| return x | |
| def g[T](x: T = cast(T, None)) -> T: # E: Name "T" is not defined | |
| return x | |
| class C: | |
| def m[T](self, x: T = cast(T, None)) -> T: # E: Name "T" is not defined | |
| return x | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695ListComprehension] | |
| from typing import cast | |
| def f[T](x: T) -> T: | |
| b = [cast(T, a) for a in [1, 2]] | |
| reveal_type(b) # N: Revealed type is "builtins.list[T`-1]" | |
| return x | |
| [case testPEP695ReuseNameInSameScope] | |
| class C[T]: | |
| def m[S](self, x: S, y: T) -> S | T: | |
| return x | |
| def m2[S](self, x: S, y: T) -> S | T: | |
| return x | |
| class D[T]: | |
| pass | |
| def f[T](x: T) -> T: | |
| return x | |
| def g[T](x: T) -> T: | |
| def nested[S](y: S) -> S: | |
| return y | |
| def nested2[S](y: S) -> S: | |
| return y | |
| return x | |
| [case testPEP695NestedScopingSpecialCases] | |
| # This is adapted from PEP 695 | |
| S = 0 | |
| def outer1[S]() -> None: | |
| S = 1 | |
| T = 1 | |
| def outer2[T]() -> None: | |
| def inner1() -> None: | |
| nonlocal S | |
| nonlocal T # E: nonlocal binding not allowed for type parameter "T" | |
| def inner2() -> None: | |
| global S | |
| [case testPEP695ScopingWithBaseClasses] | |
| # This is adapted from PEP 695 | |
| class Outer: | |
| class Private: | |
| pass | |
| # If the type parameter scope was like a traditional scope, | |
| # the base class 'Private' would not be accessible here. | |
| class Inner[T](Private, list[T]): | |
| pass | |
| # Likewise, 'Inner' would not be available in these type annotations. | |
| def method1[T](self, a: Inner[T]) -> Inner[T]: | |
| return a | |
| [case testPEP695RedefineTypeParameterInScope] | |
| class C[T]: | |
| def m[T](self, x: T) -> T: # E: "T" already defined as a type parameter | |
| return x | |
| def m2(self) -> None: | |
| def nested[T](x: T) -> T: # E: "T" already defined as a type parameter | |
| return x | |
| def f[S, S](x: S) -> S: # E: "S" already defined as a type parameter | |
| return x | |
| [case testPEP695TypeVarNameClashNoCrashForwardReference] | |
| # https://github.com/python/mypy/issues/18507 | |
| from typing import TypeVar | |
| T = TypeVar("T", bound=Foo) # E: Name "Foo" is used before definition | |
| class Foo: ... | |
| class Bar[T]: ... | |
| [case testPEP695TypeVarNameClashNoCrashDeferredSymbol] | |
| # https://github.com/python/mypy/issues/19526 | |
| T = Unknown # E: Name "Unknown" is not defined | |
| class Foo[T]: ... | |
| class Bar[*T]: ... | |
| class Baz[**T]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695TypeVarNameClashTypeAlias] | |
| type Tb = object | |
| type Ta[Tb] = 'B[Tb]' | |
| class A[Ta]: ... | |
| class B[Tb](A[Ta]): ... | |
| [case testPEP695TypeVarNameClashStarImport] | |
| # Similar to | |
| # https://github.com/python/mypy/issues/19946 | |
| import a | |
| [file a.py] | |
| from b import * | |
| class Foo[T]: ... | |
| [file b.py] | |
| from a import * | |
| class Bar[T]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695ClassDecorator] | |
| from typing import Any | |
| T = 0 | |
| def decorator(x: str) -> Any: ... | |
| @decorator(T) # E: Argument 1 to "decorator" has incompatible type "int"; expected "str" | |
| class C[T]: | |
| pass | |
| [case testPEP695RecursiceTypeAlias] | |
| type A = str | list[A] | |
| a: A | |
| reveal_type(a) # N: Revealed type is "builtins.str | builtins.list[...]" | |
| class C[T]: pass | |
| type B[T] = C[T] | list[B[T]] | |
| b: B[int] | |
| reveal_type(b) # N: Revealed type is "__main__.C[builtins.int] | builtins.list[...]" | |
| [builtins fixtures/type.pyi] | |
| [case testPEP695BadRecursiveTypeAlias] | |
| type A = A # E: Cannot resolve name "A" (possible cyclic definition) | |
| type B = B | int # E: Invalid recursive alias: a union item of itself | |
| a: A | |
| reveal_type(a) # N: Revealed type is "Any" | |
| b: B | |
| reveal_type(b) # N: Revealed type is "Any" | |
| [builtins fixtures/type.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695RecursiveTypeAliasForwardReference] | |
| def f(a: A) -> None: | |
| if isinstance(a, str): | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| else: | |
| reveal_type(a) # N: Revealed type is "__main__.C[builtins.str | __main__.C[...]]" | |
| type A = str | C[A] | |
| class C[T]: pass | |
| f('x') | |
| f(C[str]()) | |
| f(C[C[str]]()) | |
| f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "A" | |
| f(C[int]()) # E: Argument 1 to "f" has incompatible type "C[int]"; expected "A" | |
| [builtins fixtures/isinstance.pyi] | |
| [case testPEP695InvalidGenericOrProtocolBaseClass] | |
| from typing import Generic, Protocol, TypeVar | |
| S = TypeVar("S") | |
| class C[T](Generic[T]): # E: Generic[...] base class is redundant | |
| pass | |
| class C2[T](Generic[S]): # E: Generic[...] base class is redundant | |
| pass | |
| a: C[int] | |
| b: C2[int, str] | |
| class P[T](Protocol[T]): # E: No arguments expected for "Protocol" base class | |
| pass | |
| class P2[T](Protocol[S]): # E: No arguments expected for "Protocol" base class | |
| pass | |
| [case testPEP695CannotUseTypeVarFromOuterClass] | |
| class ClassG[V]: | |
| # This used to crash | |
| class ClassD[T: dict[str, V]]: # E: Name "V" is not defined | |
| ... | |
| [builtins fixtures/dict.pyi] | |
| [case testPEP695MixNewAndOldStyleGenerics] | |
| from typing import TypeVar | |
| S = TypeVar("S") | |
| U = TypeVar("U") | |
| def f[T](x: T, y: S) -> T | S: ... # E: All type parameters should be declared ("S" not declared) | |
| def g[T](x: S, y: U) -> T | S | U: ... # E: All type parameters should be declared ("S", "U" not declared) | |
| def h[S: int](x: S) -> S: | |
| a: int = x | |
| return x | |
| class C[T]: | |
| def m[X, S](self, x: S, y: U) -> X | S | U: ... # E: All type parameters should be declared ("U" not declared) | |
| def m2(self, x: T, y: S) -> T | S: ... | |
| class D[T](C[S]): # E: All type parameters should be declared ("S" not declared) | |
| pass | |
| [case testPEP695MixNewAndOldStyleTypeVarTupleAndParamSpec] | |
| from typing import TypeVarTuple, ParamSpec, Callable | |
| Ts = TypeVarTuple("Ts") | |
| P = ParamSpec("P") | |
| def f[T](x: T, f: Callable[P, None] # E: All type parameters should be declared ("P" not declared) | |
| ) -> Callable[P, T]: ... | |
| def g[T](x: T, f: tuple[*Ts] # E: All type parameters should be declared ("Ts" not declared) | |
| ) -> tuple[T, *Ts]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695MixNewAndOldStyleGenericsInTypeAlias] | |
| from typing import TypeVar, ParamSpec, TypeVarTuple, Callable | |
| T = TypeVar("T") | |
| Ts = TypeVarTuple("Ts") | |
| P = ParamSpec("P") | |
| type A = list[T] # E: All type parameters should be declared ("T" not declared) | |
| a: A[int] # E: Bad number of arguments for type alias, expected 0, given 1 | |
| reveal_type(a) # N: Revealed type is "builtins.list[Any]" | |
| type B = tuple[*Ts] # E: All type parameters should be declared ("Ts" not declared) | |
| type C = Callable[P, None] # E: All type parameters should be declared ("P" not declared) | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695NonGenericAliasToGenericClass] | |
| class C[T]: pass | |
| type A = C | |
| x: C | |
| y: A | |
| reveal_type(x) # N: Revealed type is "__main__.C[Any]" | |
| reveal_type(y) # N: Revealed type is "__main__.C[Any]" | |
| z: A[int] # E: Bad number of arguments for type alias, expected 0, given 1 | |
| [case testPEP695SelfType] | |
| from typing import Self | |
| class C: | |
| @classmethod | |
| def m[T](cls, x: T) -> tuple[Self, T]: | |
| return cls(), x | |
| class D(C): | |
| pass | |
| reveal_type(C.m(1)) # N: Revealed type is "tuple[__main__.C, builtins.int]" | |
| reveal_type(D.m(1)) # N: Revealed type is "tuple[__main__.D, builtins.int]" | |
| class E[T]: | |
| def m(self) -> Self: | |
| return self | |
| def mm[S](self, x: S) -> tuple[Self, S]: | |
| return self, x | |
| class F[T](E[T]): | |
| pass | |
| reveal_type(E[int]().m()) # N: Revealed type is "__main__.E[builtins.int]" | |
| reveal_type(E[int]().mm(b'x')) # N: Revealed type is "tuple[__main__.E[builtins.int], builtins.bytes]" | |
| reveal_type(F[str]().m()) # N: Revealed type is "__main__.F[builtins.str]" | |
| reveal_type(F[str]().mm(b'x')) # N: Revealed type is "tuple[__main__.F[builtins.str], builtins.bytes]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695CallAlias] | |
| class C: | |
| def __init__(self, x: str) -> None: ... | |
| type A = C | |
| class D[T]: pass | |
| type B[T] = D[T] | |
| reveal_type(A) # N: Revealed type is "typing.TypeAliasType" | |
| reveal_type(B) # N: Revealed type is "typing.TypeAliasType" | |
| reveal_type(B[int]) # N: Revealed type is "typing.TypeAliasType" | |
| A(1) # E: "TypeAliasType" not callable | |
| B[int]() # E: "TypeAliasType" not callable | |
| A2 = C | |
| B2 = D | |
| A2(1) # E: Argument 1 to "C" has incompatible type "int"; expected "str" | |
| B2[int]() | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695IncrementalTypeAliasKinds] | |
| import a | |
| [file a.py] | |
| from b import A | |
| [file a.py.2] | |
| from b import A, B, C | |
| A() | |
| B() | |
| C() | |
| [file b.py] | |
| from typing_extensions import TypeAlias | |
| type A = int | |
| B = int | |
| C: TypeAlias = int | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [out2] | |
| tmp/a.py:2: error: "TypeAliasType" not callable | |
| [case testPEP695TypeAliasBoundAndValueChecking] | |
| from typing import Any, cast | |
| class C: pass | |
| class D(C): pass | |
| type A[T: C] = list[T] | |
| a1: A | |
| reveal_type(a1) # N: Revealed type is "builtins.list[Any]" | |
| a2: A[Any] | |
| a3: A[C] | |
| a4: A[D] | |
| a5: A[object] # E: Type argument "object" of "A" must be a subtype of "C" | |
| a6: A[int] # E: Type argument "int" of "A" must be a subtype of "C" | |
| x1 = cast(A[C], a1) | |
| x2 = cast(A[None], a1) # E: Type argument "None" of "A" must be a subtype of "C" | |
| type A2[T: (int, C)] = list[T] | |
| b1: A2 | |
| reveal_type(b1) # N: Revealed type is "builtins.list[Any]" | |
| b2: A2[Any] | |
| b3: A2[int] | |
| b4: A2[C] | |
| b5: A2[D] # E: Value of type variable "T" of "A2" cannot be "D" | |
| b6: A2[object] # E: Value of type variable "T" of "A2" cannot be "object" | |
| list[A2[int]]() | |
| list[A2[None]]() # E: Invalid type argument value for "A2" | |
| class N(int): pass | |
| type A3[T: C, S: (int, str)] = T | S | |
| c1: A3[C, int] | |
| c2: A3[D, str] | |
| c3: A3[C, N] # E: Value of type variable "S" of "A3" cannot be "N" | |
| c4: A3[int, str] # E: Type argument "int" of "A3" must be a subtype of "C" | |
| [builtins fixtures/type.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasInClassBodyOrFunction] | |
| class C: | |
| type A = int | |
| type B[T] = list[T] | None | |
| a: A | |
| b: B[str] | |
| def method(self) -> None: | |
| v: C.A | |
| reveal_type(v) # N: Revealed type is "builtins.int" | |
| reveal_type(C.a) # N: Revealed type is "builtins.int" | |
| reveal_type(C.b) # N: Revealed type is "builtins.list[builtins.str] | None" | |
| C.A = str # E: Incompatible types in assignment (expression has type "type[str]", variable has type "TypeAliasType") | |
| x: C.A | |
| y: C.B[int] | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| reveal_type(y) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| def f() -> None: | |
| type A = int | |
| type B[T] = list[T] | None | |
| a: A | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| def g() -> None: | |
| b: B[int] | |
| reveal_type(b) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| class D: | |
| def __init__(self) -> None: | |
| type A = int | |
| self.a: A = 0 | |
| type B[T] = list[T] | |
| self.b: B[int] = [1] | |
| reveal_type(D().a) # N: Revealed type is "builtins.int" | |
| reveal_type(D().b) # N: Revealed type is "builtins.list[builtins.int]" | |
| class E[T]: | |
| type X = list[T] # E: All type parameters should be declared ("T" not declared) | |
| def __init__(self) -> None: | |
| type A = list[T] # E: All type parameters should be declared ("T" not declared) | |
| self.a: A | |
| reveal_type(E[str]().a) # N: Revealed type is "builtins.list[Any]" | |
| [builtins fixtures/type.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasInvalidGenericConstraint] | |
| class A[T]: | |
| class a[S: (int, list[T])]: pass # E: Name "T" is not defined | |
| type b[S: (int, list[T])] = S # E: TypeVar constraint type cannot be parametrized by type variables | |
| def c[S: (int, list[T])](self) -> None: ... # E: TypeVar constraint type cannot be parametrized by type variables | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasUnboundTypeVarConstraint] | |
| from typing import TypeVar | |
| T = TypeVar("T") | |
| class a[S: (int, list[T])]: pass # E: Type variable "__main__.T" is unbound \ | |
| # N: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class) \ | |
| # N: (Hint: Use "T" in function signature to bind "T" inside a function) | |
| type b[S: (int, list[T])] = S # E: Type variable "__main__.T" is unbound \ | |
| # N: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class) \ | |
| # N: (Hint: Use "T" in function signature to bind "T" inside a function) | |
| def c[S: (int, list[T])](self) -> None: ... # E: Type variable "__main__.T" is unbound \ | |
| # N: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class) \ | |
| # N: (Hint: Use "T" in function signature to bind "T" inside a function) | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695RedefineAsTypeAlias1] | |
| class C: pass | |
| type C = int # E: Name "C" already defined on line 1 | |
| A = 0 | |
| type A = str # E: Name "A" already defined on line 4 | |
| reveal_type(A) # N: Revealed type is "builtins.int" | |
| [case testPEP695RedefineAsTypeAlias2] | |
| from m import D | |
| type D = int # E: Name "D" already defined (possibly by an import) | |
| a: D | |
| reveal_type(a) # N: Revealed type is "m.D" | |
| [file m.py] | |
| class D: pass | |
| [case testPEP695RedefineAsTypeAlias3] | |
| D = list["Forward"] | |
| type D = int # E: Name "D" already defined on line 1 | |
| Forward = str | |
| x: D | |
| reveal_type(x) # N: Revealed type is "builtins.list[builtins.str]" | |
| [case testPEP695MultiDefinitionsForTypeAlias] | |
| if int(): | |
| type A[T] = list[T] | |
| else: | |
| type A[T] = str # E: Name "A" already defined on line 2 | |
| x: T # E: Name "T" is not defined | |
| a: A[int] | |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" | |
| [case testPEP695UndefinedNameInAnnotation] | |
| def f[T](x: foobar, y: T) -> T: ... # E: Name "foobar" is not defined | |
| reveal_type(f) # N: Revealed type is "def [T] (x: Any, y: T`-1) -> T`-1" | |
| [case testPEP695WrongNumberOfConstrainedTypes] | |
| # TODO: we should probably error on this. | |
| type A[T: ()] = list[T] | |
| a: A[int] | |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" | |
| type B[T: (int,)] = list[T] # E: Type variable must have at least two constrained types | |
| b: B[str] | |
| reveal_type(b) # N: Revealed type is "builtins.list[builtins.str]" | |
| class C[T: (int,)]: # E: Type variable must have at least two constrained types | |
| pass | |
| [case testPEP695UsingTypeVariableInOwnBoundOrConstraint] | |
| type A[T: list[T]] = str # E: Name "T" is not defined | |
| type B[S: (list[S], str)] = str # E: Name "S" is not defined | |
| type C[T, S: list[T]] = str # E: Name "T" is not defined | |
| def f[T: T](x: T) -> T: ... # E: Name "T" is not defined | |
| class D[T: T]: # E: Name "T" is not defined | |
| pass | |
| [case testPEP695InvalidType] | |
| def f[T: 1](x: T) -> T: ... # E: Invalid type: try using Literal[1] instead? | |
| class C[T: (int, (1 + 2))]: pass # E: Invalid type comment or annotation | |
| type A = list[1] # E: Invalid type: try using Literal[1] instead? | |
| type B = (1 + 2) # E: Invalid type alias: expression is not a valid type | |
| a: A | |
| reveal_type(a) # N: Revealed type is "builtins.list[Any]" | |
| b: B | |
| reveal_type(b) # N: Revealed type is "Any" | |
| [case testPEP695GenericNamedTuple] | |
| from typing import NamedTuple | |
| # Invariant because of the signature of the generated _replace method | |
| class N[T](NamedTuple): | |
| x: T | |
| y: int | |
| a: N[object] | |
| reveal_type(a.x) # N: Revealed type is "builtins.object" | |
| b: N[int] | |
| reveal_type(b.x) # N: Revealed type is "builtins.int" | |
| if int(): | |
| a = b # E: Incompatible types in assignment (expression has type "N[int]", variable has type "N[object]") | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "N[object]", variable has type "N[int]") | |
| class M[T: (int, str)](NamedTuple): | |
| x: T | |
| c: M[int] | |
| d: M[str] | |
| e: M[bool] # E: Value of type variable "T" of "M" cannot be "bool" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695GenericTypedDict] | |
| from typing import TypedDict | |
| class D[T](TypedDict): | |
| x: T | |
| y: int | |
| class E[T: str](TypedDict): | |
| x: T | |
| y: int | |
| a: D[object] | |
| reveal_type(a["x"]) # N: Revealed type is "builtins.object" | |
| b: D[int] | |
| reveal_type(b["x"]) # N: Revealed type is "builtins.int" | |
| c: E[str] | |
| d: E[int] # E: Type argument "int" of "E" must be a subtype of "str" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testCurrentClassWorksAsBound] | |
| from typing import Protocol | |
| class Comparable[T: Comparable](Protocol): | |
| def compare(self, other: T) -> bool: ... | |
| class Good: | |
| def compare(self, other: Good) -> bool: ... | |
| x: Comparable[Good] | |
| y: Comparable[int] # E: Type argument "int" of "Comparable" must be a subtype of "Comparable[Any]" | |
| [case testPEP695TypeAliasWithDifferentTargetTypes] | |
| import types # We need GenericAlias from here, and test stubs don't bring in 'types' | |
| from typing import Any, Callable, List, Literal, TypedDict | |
| # Test that various type expressions don't generate false positives as type alias | |
| # values, as they are type checked as expressions. There is a similar test case in | |
| # pythoneval.test that uses typeshed stubs. | |
| class C[T]: pass | |
| class TD(TypedDict): | |
| x: int | |
| type A1 = type[int] | |
| type A2 = type[int] | None | |
| type A3 = None | type[int] | |
| type A4 = type[Any] | |
| type B1[**P, R] = Callable[P, R] | None | |
| type B2[**P, R] = None | Callable[P, R] | |
| type B3 = Callable[[str], int] | |
| type B4 = Callable[..., int] | |
| type C1 = A1 | None | |
| type C2 = None | A1 | |
| type D1 = Any | None | |
| type D2 = None | Any | |
| type E1 = List[int] | |
| type E2 = List[int] | None | |
| type E3 = None | List[int] | |
| type F1 = Literal[1] | |
| type F2 = Literal['x'] | None | |
| type F3 = None | Literal[True] | |
| type G1 = tuple[int, Any] | |
| type G2 = tuple[int, Any] | None | |
| type G3 = None | tuple[int, Any] | |
| type H1 = TD | |
| type H2 = TD | None | |
| type H3 = None | TD | |
| type I1 = C[int] | |
| type I2 = C[Any] | None | |
| type I3 = None | C[TD] | |
| [builtins fixtures/type.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testTypedDictInlineYesNewStyleAlias] | |
| # flags: --enable-incomplete-feature=InlineTypedDict | |
| type X[T] = {"item": T, "other": X[T] | None} | |
| x: X[str] | |
| reveal_type(x) # N: Revealed type is "TypedDict({'item': builtins.str, 'other': ... | None})" | |
| if x["other"] is not None: | |
| reveal_type(x["other"]["item"]) # N: Revealed type is "builtins.str" | |
| type Y[T] = {"item": T, **Y[T]} # E: Overwriting TypedDict field "item" while merging | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695UsingIncorrectExpressionsInTypeVariableBound] | |
| from typing import Any | |
| type X[T: (yield 1)] = Any # E: Invalid type comment or annotation | |
| type Y[T: (yield from [])] = Any # E: Invalid type comment or annotation | |
| type Z[T: (a := 1)] = Any # E: Invalid type comment or annotation | |
| type K[T: (await 1)] = Any # E: Invalid type comment or annotation | |
| type XNested[T: (1 + (yield 1))] = Any # E: Invalid type comment or annotation | |
| type YNested[T: (1 + (yield from []))] = Any # E: Invalid type comment or annotation | |
| type ZNested[T: (1 + (a := 1))] = Any # E: Invalid type comment or annotation | |
| type KNested[T: (1 + (await 1))] = Any # E: Invalid type comment or annotation | |
| class FooX[T: (yield 1)]: pass # E: Invalid type comment or annotation | |
| class FooY[T: (yield from [])]: pass # E: Invalid type comment or annotation | |
| class FooZ[T: (a := 1)]: pass # E: Invalid type comment or annotation | |
| class FooK[T: (await 1)]: pass # E: Invalid type comment or annotation | |
| class FooXNested[T: (1 + (yield 1))]: pass # E: Invalid type comment or annotation | |
| class FooYNested[T: (1 + (yield from []))]: pass # E: Invalid type comment or annotation | |
| class FooZNested[T: (1 + (a := 1))]: pass # E: Invalid type comment or annotation | |
| class FooKNested[T: (1 + (await 1))]: pass # E: Invalid type comment or annotation | |
| def foox[T: (yield 1)](): pass # E: Invalid type comment or annotation | |
| def fooy[T: (yield from [])](): pass # E: Invalid type comment or annotation | |
| def fooz[T: (a := 1)](): pass # E: Invalid type comment or annotation | |
| def fook[T: (await 1)](): pass # E: Invalid type comment or annotation | |
| def foox_nested[T: (1 + (yield 1))](): pass # E: Invalid type comment or annotation | |
| def fooy_nested[T: (1 + (yield from []))](): pass # E: Invalid type comment or annotation | |
| def fooz_nested[T: (1 + (a := 1))](): pass # E: Invalid type comment or annotation | |
| def fook_nested[T: (1 + (await 1))](): pass # E: Invalid type comment or annotation | |
| [case testPEP695UsingIncorrectExpressionsInTypeAlias] | |
| type X = (yield 1) # E: Invalid type alias: expression is not a valid type | |
| type Y = (yield from []) # E: Invalid type alias: expression is not a valid type | |
| type Z = (a := 1) # E: Invalid type alias: expression is not a valid type | |
| type K = (await 1) # E: Invalid type alias: expression is not a valid type | |
| type XNested = (1 + (yield 1)) # E: Invalid type alias: expression is not a valid type | |
| type YNested = (1 + (yield from [])) # E: Invalid type alias: expression is not a valid type | |
| type ZNested = (1 + (a := 1)) # E: Invalid type alias: expression is not a valid type | |
| type KNested = (1 + (await 1)) # E: Invalid type alias: expression is not a valid type | |
| [case testWalrusRebindsNamesLoadedInComprehensionTargets] | |
| # Newly legal in https://github.com/python/cpython/pull/100581 | |
| from typing import Any | |
| def f(c: Any, d: Any, e: Any, f: Any, g: Any, h: Any, j: Any) -> None: | |
| ((c := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(c := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(c := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((d := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(d := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(d := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((e := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(e := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(e := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((f := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(f := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(f := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((g := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(g := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(g := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((h := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(h := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(h := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((i := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(i := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(i := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| ((j := 1) for a, (*b, c[d+e::f(g)], h.i) in j) | |
| [(j := 1) for a, (*b, c[d+e::f(g)], h.i) in j] | |
| {(j := 1) for a, (*b, c[d+e::f(g)], h.i) in j} | |
| [builtins fixtures/primitives.pyi] | |
| [case testPEP695TypeAliasAndAnnotated] | |
| from typing_extensions import Annotated, Annotated as _Annotated | |
| import typing_extensions as t | |
| def ann(*args): ... | |
| type A = Annotated[int, ann()] | |
| type B = Annotated[int | str, ann((1, 2))] | |
| type C = _Annotated[int, ann()] | |
| type D = t.Annotated[str, ann()] | |
| x: A | |
| y: B | |
| z: C | |
| zz: D | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| reveal_type(y) # N: Revealed type is "builtins.int | builtins.str" | |
| reveal_type(z) # N: Revealed type is "builtins.int" | |
| reveal_type(zz) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695NestedGenericClass1] | |
| class C[T]: | |
| def f(self) -> T: ... | |
| class A: | |
| class B[Q]: | |
| def __init__(self, a: Q) -> None: | |
| self.a = a | |
| def f(self) -> Q: | |
| return self.a | |
| def g(self, x: Q) -> None: ... | |
| b: B[str] | |
| x: A.B[int] | |
| x.g("x") # E: Argument 1 to "g" of "B" has incompatible type "str"; expected "int" | |
| reveal_type(x.a) # N: Revealed type is "builtins.int" | |
| reveal_type(x) # N: Revealed type is "__main__.A.B[builtins.int]" | |
| reveal_type(A.b) # N: Revealed type is "__main__.A.B[builtins.str]" | |
| [case testPEP695NestedGenericClass2] | |
| class A: | |
| def m(self) -> None: | |
| class B[T]: | |
| def f(self) -> T: ... | |
| x: B[int] | |
| reveal_type(x.f()) # N: Revealed type is "builtins.int" | |
| self.a = B[str]() | |
| reveal_type(A().a) # N: Revealed type is "__main__.B@3[builtins.str]" | |
| reveal_type(A().a.f()) # N: Revealed type is "builtins.str" | |
| [case testPEP695NestedGenericClass3] | |
| class C[T]: | |
| def f(self) -> T: ... | |
| class D[S]: | |
| x: T # E: Name "T" is not defined | |
| def g(self) -> S: ... | |
| a: C[int] | |
| reveal_type(a.f()) # N: Revealed type is "builtins.int" | |
| b: C.D[str] | |
| reveal_type(b.g()) # N: Revealed type is "builtins.str" | |
| class E[T]: | |
| class F[T]: # E: "T" already defined as a type parameter | |
| x: T | |
| c: E.F[int] | |
| [case testPEP695NestedGenericClass4] | |
| class A: | |
| class B[T]: | |
| def __get__(self, instance: A, owner: type[A]) -> T: | |
| return None # E: Incompatible return value type (got "None", expected "T") | |
| f = B[int]() | |
| a = A() | |
| v = a.f | |
| [case testPEP695VarianceInheritedFromBaseWithExplicitVariance] | |
| from typing import TypeVar, Generic | |
| T = TypeVar("T") | |
| class ParentInvariant(Generic[T]): | |
| pass | |
| class Invariant1[T](ParentInvariant[T]): | |
| pass | |
| a1: Invariant1[int] = Invariant1[float]() # E: Incompatible types in assignment (expression has type "Invariant1[float]", variable has type "Invariant1[int]") | |
| a2: Invariant1[float] = Invariant1[int]() # E: Incompatible types in assignment (expression has type "Invariant1[int]", variable has type "Invariant1[float]") | |
| T_contra = TypeVar("T_contra", contravariant=True) | |
| class ParentContravariant(Generic[T_contra]): | |
| pass | |
| class Contravariant[T](ParentContravariant[T]): | |
| pass | |
| b1: Contravariant[int] = Contravariant[float]() | |
| b2: Contravariant[float] = Contravariant[int]() # E: Incompatible types in assignment (expression has type "Contravariant[int]", variable has type "Contravariant[float]") | |
| class Invariant2[T](ParentContravariant[T]): | |
| def f(self) -> T: ... | |
| c1: Invariant2[int] = Invariant2[float]() # E: Incompatible types in assignment (expression has type "Invariant2[float]", variable has type "Invariant2[int]") | |
| c2: Invariant2[float] = Invariant2[int]() # E: Incompatible types in assignment (expression has type "Invariant2[int]", variable has type "Invariant2[float]") | |
| class Multi[T, S](ParentInvariant[T], ParentContravariant[S]): | |
| pass | |
| d1: Multi[int, str] = Multi[float, str]() # E: Incompatible types in assignment (expression has type "Multi[float, str]", variable has type "Multi[int, str]") | |
| d2: Multi[float, str] = Multi[int, str]() # E: Incompatible types in assignment (expression has type "Multi[int, str]", variable has type "Multi[float, str]") | |
| d3: Multi[str, int] = Multi[str, float]() | |
| d4: Multi[str, float] = Multi[str, int]() # E: Incompatible types in assignment (expression has type "Multi[str, int]", variable has type "Multi[str, float]") | |
| [case testPEP695MultipleNestedGenericClass1] | |
| class A: | |
| class B: | |
| class C: | |
| class D[Q]: | |
| def g(self, x: Q): ... | |
| d: D[str] | |
| x: A.B.C.D[int] | |
| x.g('a') # E: Argument 1 to "g" of "D" has incompatible type "str"; expected "int" | |
| reveal_type(x) # N: Revealed type is "__main__.A.B.C.D[builtins.int]" | |
| reveal_type(A.B.C.d) # N: Revealed type is "__main__.A.B.C.D[builtins.str]" | |
| [case testPEP695MultipleNestedGenericClass2] | |
| class A: | |
| class B: | |
| def m(self) -> None: | |
| class C[T]: | |
| def f(self) -> T: ... | |
| x: C[int] | |
| reveal_type(x.f()) # N: Revealed type is "builtins.int" | |
| self.a = C[str]() | |
| reveal_type(A().B().a) # N: Revealed type is "__main__.C@4[builtins.str]" | |
| [case testPEP695MultipleNestedGenericClass3] | |
| class A: | |
| class C[T]: | |
| def f(self) -> T: ... | |
| class D[S]: | |
| x: T # E: Name "T" is not defined | |
| def g(self) -> S: ... | |
| a: A.C[int] | |
| reveal_type(a.f()) # N: Revealed type is "builtins.int" | |
| b: A.C.D[str] | |
| reveal_type(b.g()) # N: Revealed type is "builtins.str" | |
| class B: | |
| class E[T]: | |
| class F[T]: # E: "T" already defined as a type parameter | |
| x: T | |
| c: B.E.F[int] | |
| [case testPEP695MultipleNestedGenericClass4] | |
| class Z: | |
| class A: | |
| class B[T]: | |
| def __get__(self, instance: Z.A, owner: type[Z.A]) -> T: | |
| return None # E: Incompatible return value type (got "None", expected "T") | |
| f = B[int]() | |
| a = Z.A() | |
| v = a.f | |
| [case testPEP695MultipleNestedGenericClass5] | |
| from a.b.c import d | |
| x: d.D.E.F.G[int] | |
| x.g('a') # E: Argument 1 to "g" of "G" has incompatible type "str"; expected "int" | |
| reveal_type(x) # N: Revealed type is "a.b.c.d.D.E.F.G[builtins.int]" | |
| reveal_type(d.D.E.F.d) # N: Revealed type is "a.b.c.d.D.E.F.G[builtins.str]" | |
| [file a/b/c/d.py] | |
| class D: | |
| class E: | |
| class F: | |
| class G[Q]: | |
| def g(self, x: Q): ... | |
| d: G[str] | |
| [case testTypeAliasNormalization] | |
| from collections.abc import Callable | |
| from typing import Unpack | |
| from typing_extensions import TypeAlias | |
| type RK_function_args = tuple[float, int] | |
| type RK_functionBIS = Callable[[Unpack[RK_function_args], int], int] | |
| def ff(a: float, b: int, c: int) -> int: | |
| return 2 | |
| bis: RK_functionBIS = ff | |
| res: int = bis(1.0, 2, 3) | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasNotReadyClass] | |
| class CustomizeResponse: | |
| related_resources: "ResourceRule" | |
| class ResourceRule: pass | |
| class DecoratorController: | |
| type CustomizeResponse = CustomizeResponse | |
| x: DecoratorController.CustomizeResponse | |
| reveal_type(x.related_resources) # N: Revealed type is "__main__.ResourceRule" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695TypeAliasRecursiveOuterClass] | |
| class A: | |
| type X = X # E: Cannot resolve name "X" (possible cyclic definition) | |
| class X: ... | |
| class AA: | |
| XX = XX # OK, we allow this as a special case. | |
| class XX: ... | |
| class Y: ... | |
| class B: | |
| type Y = Y | |
| reveal_type(AA.XX) # N: Revealed type is "def () -> __main__.XX" | |
| y: B.Y | |
| reveal_type(y) # N: Revealed type is "__main__.Y" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasRecursiveInvalid] | |
| type X = X # E: Cannot resolve name "X" (possible cyclic definition) | |
| type Z = Z[int] # E: Cannot resolve name "Z" (possible cyclic definition) | |
| def foo() -> None: | |
| type X = X # OK, refers to outer (invalid) X | |
| x: X | |
| reveal_type(x) # N: Revealed type is "Any" | |
| type Y = Y # E: Cannot resolve name "Y" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| class Z: ... # E: Name "Z" already defined on line 2 | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695MultipleUnpacksInBareApplicationNoCrash] | |
| # https://github.com/python/mypy/issues/18856 | |
| class A[*Ts]: ... | |
| A[*tuple[int, ...], *tuple[int, ...]] # E: More than one variadic Unpack in a type is not allowed | |
| A[*tuple[*tuple[int, ...]], *tuple[*tuple[int, ...]]] # E: More than one variadic Unpack in a type is not allowed | |
| a: A[*tuple[int, ...], *tuple[int, ...]] # E: More than one variadic Unpack in a type is not allowed | |
| def foo(a: A[*tuple[int, ...], *tuple[int, ...]]): ... # E: More than one variadic Unpack in a type is not allowed | |
| tuple[*tuple[int, ...], *tuple[int, ...]] # E: More than one variadic Unpack in a type is not allowed | |
| b: tuple[*tuple[int, ...], *tuple[int, ...]] # E: More than one variadic Unpack in a type is not allowed | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testForwardNestedPrecedesForwardGlobal] | |
| from typing import NewType | |
| class W[T]: pass | |
| class R: | |
| class M(W[Action.V], type): | |
| FOO = R.Action.V(0) | |
| class Action(metaclass=M): | |
| V = NewType('V', int) | |
| class Action: | |
| pass | |
| [case testPEP695TypeVarConstraintsDefaultAliases] | |
| from typing import Generic | |
| from typing_extensions import TypeVar | |
| type K = int | |
| type V = int | |
| type L = list[int] | |
| T1 = TypeVar("T1", str, K, default=K) | |
| T2 = TypeVar("T2", str, K, default=V) | |
| T3 = TypeVar("T3", str, L, default=L) | |
| class A1(Generic[T1]): | |
| x: T1 | |
| class A2(Generic[T2]): | |
| x: T2 | |
| class A3(Generic[T3]): | |
| x: T3 | |
| reveal_type(A1().x) # N: Revealed type is "builtins.int" | |
| reveal_type(A2().x) # N: Revealed type is "builtins.int" | |
| reveal_type(A3().x) # N: Revealed type is "builtins.list[builtins.int]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testDataclassWithTypeVarTuple] | |
| # flags: --python-version 3.13 | |
| # https://github.com/python/mypy/issues/19559 | |
| from typing import Callable | |
| from dataclasses import dataclass | |
| @dataclass | |
| class Test[*Ts, R]: | |
| a: Callable[[*Ts], R] | |
| [builtins fixtures/dict.pyi] | |
| [case testPEP695AliasDoesNotReferToFullname] | |
| # https://github.com/python/mypy/issues/19698 | |
| from typing import TypeAliasType | |
| type D = dict | |
| type T = type | |
| type TA = TypeAliasType | |
| D() # E: "TypeAliasType" not callable | |
| X = TA("Y") # E: "TypeAliasType" not callable | |
| x: object | |
| if T(x) is str: # E: "TypeAliasType" not callable | |
| reveal_type(x) # N: Revealed type is "builtins.object" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasForwardReferenceInUnusedTypeVar] | |
| # https://discuss.python.org/t/103305 | |
| type Alias1[T: "A"] = int | |
| type Alias2[T: ("A", int)] = int | |
| class A: ... | |
| x1: Alias1[A] # ok | |
| x2: Alias2[A] # ok | |
| [case testUndefinedUnpackInPEP696Base] | |
| # Typo below is intentional. | |
| class MyTuple[*Ts](tuple[*TS]): # E: Name "TS" is not defined | |
| ... | |
| x: MyTuple[int, str] | |
| reveal_type(x[0]) # N: Revealed type is "Any" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testAnnotatedWithCallableAsParameterTypeKeyword] | |
| from typing_extensions import Annotated | |
| def something() -> None: ... | |
| type A = list[Annotated[str, something()]] | |
| a: A | |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.str]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testAnnotatedWithCallableAsParameterTypeKeywordDeeper] | |
| from typing_extensions import Annotated | |
| def something() -> None: ... | |
| type A = list[Annotated[Annotated[str, something()], something()]] | |
| a: A | |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.str]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695TypeAliasRecursiveInParameterBound] | |
| from typing import Any | |
| type A1[T: B1] = list[int] | |
| type B1 = None | A1[B1] | |
| x1: A1[B1] | |
| y1: A1[int] # E: Type argument "int" of "A1" must be a subtype of "B1" | |
| z1: A1[None] | |
| type A2[T: B2] = list[T] | |
| type B2 = None | A2[Any] | |
| x2: A2[B2] | |
| y2: A2[int] # E: Type argument "int" of "A2" must be a subtype of "B2" | |
| z2: A2[None] | |
| type A3[T: B3] = list[T] | |
| type B3 = None | A3[B3] | |
| x3: A3[B3] | |
| y3: A3[int] # E: Type argument "int" of "A3" must be a subtype of "B3" | |
| z3: A3[None] | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695TypeAliasRecursiveTupleUnionNoCrash] | |
| from collections.abc import Hashable | |
| type HashableArg = int | tuple[Hashable | HashableArg] | |
| x: HashableArg | |
| reveal_type(x) # N: Revealed type is "builtins.int | tuple[typing.Hashable | ...]" | |
| if isinstance(x, tuple): | |
| y, = x | |
| reveal_type(y) # N: Revealed type is "typing.Hashable | builtins.int | tuple[typing.Hashable | ...]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testPEP695MultipleTypeVarTuples] | |
| from typing import Generic | |
| from typing_extensions import TypeVarTuple, Unpack | |
| Us = TypeVarTuple("Us") | |
| class C[*Ts, *Us]: # E: Can only use one type var tuple in a class def | |
| pass | |
| class D[*Ts](Generic[Unpack[Us]]): # E: Generic[...] base class is redundant \ | |
| # E: Can only use one type var tuple in a class def | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testPEP695VariadicAliasUnpack] | |
| class C[*Ts]: | |
| pass | |
| type T[T, *Ts] = C[*Ts] | |
| x: T[bool, *tuple[()]] | |
| reveal_type(x) # N: Revealed type is "__main__.C[()]" | |
| y: T[bool] | |
| reveal_type(y) # N: Revealed type is "__main__.C[()]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testTupleBaseTupleTypeUnpack] | |
| class X(tuple[*tuple[int], *tuple[int]]): | |
| pass | |
| x = X((1, 2)) | |
| reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.X]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNewTypeTupleTypeUnpack] | |
| from typing import NewType | |
| T = NewType("T", tuple[*tuple[int], *tuple[int]]) | |
| t = T((1, 2)) | |
| reveal_type(t) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.T]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleTupleTypeUnpack] | |
| from typing import NamedTuple | |
| class N(NamedTuple): | |
| x: tuple[*tuple[int], *tuple[int]] | |
| n = N((1, 2)) | |
| reveal_type(n) # N: Revealed type is "tuple[tuple[builtins.int, builtins.int], fallback=__main__.N]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testAliasWithTypeVarDefaultPlaceholderInImportCycleNewSyntax] | |
| import a | |
| from a import Base | |
| reveal_type(Base().inst()) # N: Revealed type is "c.Inst" | |
| reveal_type(Base().group()) # N: Revealed type is "TypedDict('d.Group', {'params': builtins.tuple[a.Base[c.Inst] | (def ()), ...]})" | |
| [file a.py] | |
| from typing import Generic, TYPE_CHECKING, TypeVar | |
| if TYPE_CHECKING: | |
| from c import Inst | |
| from d import Group | |
| T = TypeVar("T", default="Inst") | |
| class Base(Generic[T]): | |
| def group(self) -> "Group": ... | |
| def inst(self) -> T: ... | |
| [file b.py] | |
| from typing import Callable, Union | |
| from a import Base | |
| type Alias = Union[Base, Callable[[], None]] | |
| [file c.py] | |
| from a import Base | |
| class Inst: | |
| def make(self) -> Base: ... | |
| [file d.py] | |
| from typing import TYPE_CHECKING, Tuple | |
| from typing_extensions import TypedDict | |
| if TYPE_CHECKING: | |
| from b import Alias | |
| class Group(TypedDict): | |
| params: "Tuple[Alias, ...]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testUnwrapUnionNewSyntaxPrecise] | |
| from typing import Sequence | |
| class A: ... | |
| class B: ... | |
| class C: ... | |
| type ThingOrA[T] = T | A | |
| def foo[T](x: ThingOrA[T]) -> T: ... | |
| obj: B | C | |
| reveal_type(foo(obj)) # N: Revealed type is "__main__.B | __main__.C" | |
| obj_a: A | B | C | |
| reveal_type(foo(obj_a)) # N: Revealed type is "__main__.B | __main__.C" | |
| def bar[T](xs: list[ThingOrA[T]]) -> list[T]: ... | |
| objs: list[B | C] | |
| objs_a: list[A | B | C] | |
| reveal_type(bar(objs_a)) # N: Revealed type is "builtins.list[__main__.B | __main__.C]" | |
| bar(objs) # E: Argument 1 to "bar" has incompatible type "list[B | C]"; expected "list[B | C | A]" \ | |
| # N: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ | |
| # N: Consider using "Sequence" instead, which is covariant | |
| def baz[T](xs: Sequence[ThingOrA[T]]) -> list[T]: ... | |
| reveal_type(baz(objs)) # N: Revealed type is "builtins.list[__main__.B | __main__.C]" | |
| reveal_type(baz(objs_a)) # N: Revealed type is "builtins.list[__main__.B | __main__.C]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testDeferredNestedTupleAliasNewSyntax] | |
| type Inner = tuple[int, str] | |
| type Outer = tuple[bool, *Inner] | |
| class K(Base): | |
| q: list[Outer] = list() | |
| class Base: ... | |
| reveal_type(K.q) # N: Revealed type is "builtins.list[tuple[builtins.bool, builtins.int, builtins.str]]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testTypeVarTupleCapturedByParamSpec_no_verbose_reveal] | |
| from typing import Callable | |
| class capture[**P, R]: | |
| def __init__(self, func: Callable[P, R]): ... | |
| def __call__(self, *args: P.args, **kwargs: P.kwargs) -> C[P, R]: ... | |
| class C[**P, R]: ... | |
| @capture | |
| def print_args[*Ts](*args: *Ts) -> tuple[*Ts]: ... | |
| reveal_type(print_args(2)) # N: Revealed type is "__main__.C[[Literal[2]?], tuple[Literal[2]?]]" | |
| def test[*Us](*xs: *Us) -> None: | |
| # TODO: we should erase last_known_values from Parameters. | |
| reveal_type(print_args(2, *xs, 4)) # N: Revealed type is "__main__.C[[Literal[2]?, *args: *tuple[*Us, Literal[4]?]], tuple[Literal[2]?, *Us, Literal[4]?]]" | |
| [builtins fixtures/paramspec.pyi] |