blob: a5a3f058d1e2f560d1836520912d9ab5855c4e9d [file] [log] [blame] [edit]
[case testPEP695Basics]
from typing import Any, 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])
[typing fixtures/typing-full.pyi]
[case testPEP695GenericTypeAlias]
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
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:
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:
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:
assert str(D[[int, str]]) == "D[[int, str]]"
assert str(getattr(D, "__value__")) == "typing.Callable[P, int]"
[typing fixtures/typing-full.pyi]