[case testPEP695Basics] from enum import Enum from typing import Any, Literal, TypeAliasType, cast from testutil import assertRaises def id[T](x: T) -> T: return x def test_call_generic_function() -> None: assert id(2) == 2 assert id('x') == 'x' class C[T]: x: T def __init__(self, x: T) -> None: self.x = x class D[T, S]: x: T y: S def __init__(self, x: T, y: S) -> None: self.x = x self.y = y def set(self, x: object, y: object) -> None: self.x = cast(T, x) self.y = cast(S, y) def test_generic_class() -> None: c = C(5) assert c.x == 5 c2 = C[str]('x') assert c2.x == 'x' d = D[str, int]('a', 5) assert d.x == 'a' assert d.y == 5 d.set('b', 6) assert d.x == 'b' assert d.y == 6 def test_generic_class_via_any() -> None: c_any: Any = C c = c_any(2) assert c.x == 2 c2 = c_any[str]('y') assert c2.x == 'y' assert str(c_any[str]) == 'native.C[str]' d_any: Any = D d = d_any(1, 'x') assert d.x == 1 assert d.y == 'x' d2 = d_any[int, str](2, 'y') assert d2.x == 2 assert d2.y == 'y' with assertRaises(TypeError): c_any[int, str] with assertRaises(TypeError): d_any[int] class E[*Ts]: pass def test_type_var_tuple() -> None: e: E[int, str] = E() e_any: Any = E assert isinstance(e_any(), E) assert isinstance(e_any[int](), E) assert isinstance(e_any[int, str](), E) class F[**P]: pass def test_param_spec() -> None: f: F[[int, str]] = F() f_any: Any = F assert isinstance(f_any(), F) assert isinstance(f_any[[int, str]](), F) class SubC[S](C[S]): def __init__(self, x: S) -> None: super().__init__(x) def test_generic_subclass() -> None: s = SubC(1) assert s.x == 1 s2 = SubC[str]('y') assert s2.x == 'y' sub_any: Any = SubC assert sub_any(1).x == 1 assert sub_any[str]('x').x == 'x' assert isinstance(s, SubC) assert isinstance(s, C) class SubD[ T, # Put everything on separate lines S]( D[T, S]): pass def test_generic_subclass_two_params() -> None: s = SubD(3, 'y') assert s.x == 3 assert s.y == 'y' s2 = SubD[str, int]('z', 4) assert s2.x == 'z' assert s2.y == 4 sub_any: Any = SubD assert sub_any(3, 'y').y == 'y' assert sub_any[int, str](3, 'y').y == 'y' assert isinstance(s, SubD) assert isinstance(s, D) class SubE[*Ts](E[*Ts]): pass def test_type_var_tuple_subclass() -> None: sub_any: Any = SubE assert isinstance(sub_any(), SubE) assert isinstance(sub_any(), E) assert isinstance(sub_any[int](), SubE) assert isinstance(sub_any[int, str](), SubE) class SubF[**P](F[P]): pass def test_param_spec_subclass() -> None: sub_any: Any = SubF assert isinstance(sub_any(), SubF) assert isinstance(sub_any(), F) assert isinstance(sub_any[[int]](), SubF) assert isinstance(sub_any[[int, str]](), SubF) # We test that upper bounds and restricted values can be used, but not that # they are introspectable def bound[T: C](x: T) -> T: return x def test_function_with_upper_bound() -> None: c = C(1) assert bound(c) is c def restriction[T: (int, str)](x: T) -> T: return x def test_function_with_value_restriction() -> None: assert restriction(1) == 1 assert restriction('x') == 'x' class Bound[T: C]: def __init__(self, x: T) -> None: self.x = x def test_class_with_upper_bound() -> None: c = C(1) b = Bound(c) assert b.x is c b2 = Bound[C](c) assert b2.x is c class Restriction[T: (int, str)]: def __init__(self, x: T) -> None: self.x = x def test_class_with_value_restriction() -> None: r = Restriction(1) assert r.x == 1 r2 = Restriction[str]('a') assert r2.x == 'a' type A = int def test_simple_type_alias() -> None: assert isinstance(A, TypeAliasType) assert getattr(A, "__value__") is int assert str(A) == "A" type B = Fwd[int] Fwd = list def test_forward_reference_in_alias() -> None: assert isinstance(B, TypeAliasType) assert getattr(B, "__value__") == list[int] type R = int | list[R] def test_recursive_type_alias() -> None: assert isinstance(R, TypeAliasType) assert getattr(R, "__value__") == (int | list[R]) class SomeEnum(Enum): AVALUE = "a" type EnumLiteralAlias1 = Literal[SomeEnum.AVALUE] type EnumLiteralAlias2 = Literal[SomeEnum.AVALUE] | None EnumLiteralAlias3 = Literal[SomeEnum.AVALUE] | None [typing fixtures/typing-full.pyi] [case testPEP695GenericTypeAlias] import sys from typing import Callable from types import GenericAlias from testutil import assertRaises type A[T] = list[T] def test_generic_alias() -> None: assert type(A[str]) is GenericAlias if sys.version_info >= (3, 15): # type: ignore[operator] assert str(A[str]) == "_frozen_importlib.A[str]" else: assert str(A[str]) == "A[str]" assert str(getattr(A, "__value__")) == "list[T]" type B[T, S] = dict[S, T] def test_generic_alias_with_two_args() -> None: if sys.version_info >= (3, 15): # type: ignore[operator] assert str(B[str, int]) == "_frozen_importlib.B[str, int]" else: assert str(B[str, int]) == "B[str, int]" assert str(getattr(B, "__value__")) == "dict[S, T]" type C[*Ts] = tuple[*Ts] def test_type_var_tuple_type_alias() -> None: if sys.version_info >= (3, 15): # type: ignore[operator] assert str(C[int, str]) == "_frozen_importlib.C[int, str]" else: assert str(C[int, str]) == "C[int, str]" assert str(getattr(C, "__value__")) == "tuple[typing.Unpack[Ts]]" type D[**P] = Callable[P, int] def test_param_spec_type_alias() -> None: if sys.version_info >= (3, 15): # type: ignore[operator] assert str(D[[int, str]]) == "_frozen_importlib.D[[int, str]]" else: assert str(D[[int, str]]) == "D[[int, str]]" assert str(getattr(D, "__value__")) == "typing.Callable[P, int]" [typing fixtures/typing-full.pyi]