2Tests for type parameter default values that reference other type parameters.
5# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#defaults-for-type-parameters.
7# > To use another type parameter as a default the ``default`` and the
8# > type parameter must be the same type (a ``TypeVar``'s default must be
9# > a ``TypeVar``, etc.).
11from typing import Any, Generic, assert_type
12from typing_extensions import TypeVar
14DefaultStrT = TypeVar("DefaultStrT", default=str)
15StartT = TypeVar("StartT", default=int)
16StopT = TypeVar("StopT", default=StartT)
17StepT = TypeVar("StepT", default=int | None)
20class slice(Generic[StartT, StopT, StepT]): ...
23assert_type(slice, type[slice[int, int, int | None]])
24assert_type(slice(), slice[int, int, int | None])
25assert_type(slice[str](), slice[str, str, int | None])
26assert_type(slice[str, bool, complex](), slice[str, bool, complex])
28T2 = TypeVar("T2", default=DefaultStrT)
31class Foo(Generic[DefaultStrT, T2]):
32 def __init__(self, a: DefaultStrT, b: T2) -> None: ...
35assert_type(Foo(1, ""), Foo[int, str])
36Foo[int](1, "") # E: Foo[int, str] cannot be assigned to self: Foo[int, int] in Foo.__init__
[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int`, found `Literal[""]`
37Foo[int]("", 1) # E: Foo[str, int] cannot be assigned to self: Foo[int, int] in Foo.__init__
[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int`, found `Literal[""]`
40# > ``T1`` must be used before ``T2`` in the parameter list of the generic.
43S2 = TypeVar("S2", default=S1)
46class Foo2(Generic[S1, S2]): ... # OK
49Start2T = TypeVar("Start2T", default="StopT")
50Stop2T = TypeVar("Stop2T", default=int)
53class slice2(Generic[Start2T, Stop2T, StepT]): ... # E: bad ordering
Expected a ty diagnostic for this line
56# > Using a type parameter from an outer scope as a default is not supported.
59class Foo3(Generic[S1]):
60 class Bar2(Generic[S2]): ... # E
Expected a ty diagnostic for this line
63# > ``T1``'s bound must be a subtype of ``T2``'s bound.
65X1 = TypeVar("X1", bound=int)
66Ok1 = TypeVar("Ok1", default=X1, bound=float) # OK
67AlsoOk1 = TypeVar("AlsoOk1", default=X1, bound=int) # OK
68Invalid1 = TypeVar("Invalid1", default=X1, bound=str) # E: int is not a subtype of str
[invalid-type-variable-default] Default `X1` of TypeVar `Invalid1` is not assignable to upper bound `str` of `Invalid1` because its upper bound `int` is not assignable to `str`
71# > The constraints of ``T2`` must be a superset of the constraints of ``T1``.
73Y1 = TypeVar("Y1", bound=int)
74Invalid2 = TypeVar("Invalid2", float, str, default=Y1) # E: upper bound int is incompatible with constraints float or str
[invalid-type-variable-default] TypeVar default is inconsistent with the TypeVar's constraints: Bounded TypeVar cannot be used as the default for a constrained TypeVar
76Y2 = TypeVar("Y2", int, str)
77AlsoOk2 = TypeVar("AlsoOk2", int, str, bool, default=Y2) # OK
78AlsoInvalid2 = TypeVar("AlsoInvalid2", bool, complex, default=Y2) # E: {bool, complex} is not a superset of {int, str}
[invalid-type-variable-default] Default `Y2` of TypeVar `AlsoInvalid2` is inconsistent with its constraints `AlsoInvalid2` because constraint `int` of `Y2` is not one of the constraints of `AlsoInvalid2`
81# > Type parameters are valid as parameters to generics inside of a
82# > ``default`` when the first parameter is in scope as determined by the
83# > `previous section <scoping rules_>`_.
87ListDefaultT = TypeVar("ListDefaultT", default=list[Z1]) # OK
90class Bar(Generic[Z1, ListDefaultT]): # OK
91 def __init__(self, x: Z1, y: ListDefaultT): ...
94assert_type(Bar, type[Bar[Any, list[Any]]])
Unexpected error
[type-assertion-failure] Type `type[Bar[Any, list[Any]]]` does not match asserted type `<class 'Bar'>`
95assert_type(Bar[int], type[Bar[int, list[int]]])
96assert_type(Bar[int](0, []), Bar[int, list[int]])
97assert_type(Bar[int, list[str]](0, []), Bar[int, list[str]])
98assert_type(Bar[int, str](0, ""), Bar[int, str])