# This sample tests error handling for variadic type var usage. # pyright: reportMissingModuleSource=false from typing import Any, Callable, Dict, Generic, Tuple, TypeVar, Union from typing_extensions import TypeVarTuple, Unpack _Xs = TypeVarTuple("_Xs") _Ys = TypeVarTuple("_Ys") _T1 = TypeVar("_T1") # This should generate an error because only one TypeVarTuple is allowed. class Class1(Generic[Unpack[_Ys], Unpack[_Xs]]): ... # This should generate an error because only one TypeVarTuple is allowed. class Class2(Dict[Tuple[Unpack[_Ys]], Tuple[Unpack[_Xs]]]): ... # This should generate an error because a TypeVarTuple must come at the end. class Class3(Dict[Tuple[Unpack[_Ys]], _T1]): ... # This should generate an error because a TypeVarTuple must come at the end. class Class4(Dict[_T1, Tuple[Unpack[_Ys]]], Generic[Unpack[_Ys], _T1]): ...
# This sample tests the handling of variadic type variables when used # in conjunction with unpacked tuples. from __future__ import annotations from typing import Any, Generic, Literal, NewType, Tuple, TypeVar, Union from typing_extensions import TypeVarTuple, Unpack DType = TypeVar("DType") Shape = TypeVarTuple("Shape") Batch = NewType("Batch", int) Height = NewType("Height", int) Width = NewType("Width", int) Channels = NewType("Channels", int) class Array(Generic[DType, Unpack[Shape]]): def __abs__(self) -> Array[DType, Unpack[Shape]]: ... def __add__( self, other: Array[DType, Unpack[Shape]]) -> Array[DType, Unpack[Shape]]: ... def process_batch_channels( x: Array[Batch, Unpack[Tuple[Any, ...]], Channels]) -> None: ...
# This sample tests various conditions under which Unpack # can and cannot be used. # pyright: reportMissingModuleSource=false from typing import Generic, List, Tuple, TypeVar, Union from typing_extensions import TypeVarTuple, Unpack _T = TypeVar("_T") _Xs = TypeVarTuple("_Xs") class ClassA(Generic[_T, Unpack[_Xs]]): def __init__(self, *shape: Unpack[_Xs]): self.x: Tuple[Unpack[_Xs]] = shape # This should generate an error self.y: _Xs = shape def func1(self) -> Union[Unpack[_Xs]]: ... # This should generate an error def func2(self) -> Tuple[Unpack[_T]]: ... # This should generate an error def func3(self) -> Tuple[Unpack[int]]: ...
# This sample tests the handling of variadic type variables used # in generic type aliases and with suffixes. from typing import Callable, Generic, TypeVar from typing_extensions import TypeVarTuple, Unpack P = TypeVarTuple("P") T = TypeVar("T", covariant=True) class Call(Generic[Unpack[P]]): def __init__(self, *args: Unpack[P]) -> None: self.args = args class Return(Generic[T]): def __init__(self, /, result: T) -> None: self.result = result TailRec = Call[Unpack[P]] | Return[T] def tail_rec( fn: Callable[[Unpack[P]], TailRec[Unpack[P], T]]) -> Callable[[Unpack[P]], T]: ... @tail_rec def factorial(n: int, acc: int) -> TailRec[int, int, int]:
# This sample tests packing and unpacking operations with # variadic type variables. # pyright: reportMissingModuleSource=false from typing import Generic, Literal, NewType, Tuple, Union from typing_extensions import TypeVarTuple, Unpack Shape = TypeVarTuple("Shape") class Array(Generic[Unpack[Shape]]): def __init__(self, *shape: Unpack[Shape]): self.shape = shape def __abs__(self) -> "Array[Unpack[Shape]]": ... def __add__(self, other: "Array[Unpack[Shape]]") -> "Array[Unpack[Shape]]": ... Height = NewType("Height", int) Width = NewType("Width", int) x: Array[Height, Width] = Array(Height(480), Width(640)) t1: Literal["tuple[Height, Width]"] = reveal_type(x.shape) t2: Literal["Array[Height, Width]"] = reveal_type(abs(x)) t3: Literal["Array[Height, Width]"] = reveal_type(x + abs(x)) _Xs = TypeVarTuple("_Xs")
# This sample tests the callable syntax described in PEP 677. from typing import Callable, Concatenate, ParamSpec, TypeVar from typing_extensions import TypeVarTuple, Unpack P = ParamSpec("P") T = TypeVar("T") Ts = TypeVarTuple("Ts") def func0( a: (int, str) -> float, b: (int | str) -> (int | str), c: (...) -> (complex, str) -> int | None ) -> (int, str) -> None: ... reveal_type(func0, expected_text='(a: (int, str) -> float, b: (int | str) -> (int | str), c: (...) -> ((complex, str) -> int | None)) -> ((int, str) -> None)') def func1() -> async (int, str) -> bool: ... reveal_type(func1, expected_text='() -> ((int, str) -> Awaitable[bool])') def func2() -> ((int, str) -> bool): ... reveal_type(func2, expected_text='() -> ((int, str) -> bool)') def func3() -> (int) -> (str) -> bool: ... reveal_type(func3, expected_text='() -> ((int) -> ((str) -> bool))') def func4() -> ((int) -> ((str) -> bool)): ...
# This sample tests the matching of a traditional *args parameter # and a *args unpacked Tuple to a *args TypeVarTuple. from typing import Callable, TypeVar from typing_extensions import TypeVarTuple Ts = TypeVarTuple('Ts') R = TypeVar('R') def call_with_params(func: Callable[[*Ts], R], *params: *Ts) -> R: # This should generate an error because it's missing a *. func(params) return func(*params) def callback1(*args: int) -> int: ... def callback2(*args: *tuple[int, int]) -> int: ... call_with_params(callback1) call_with_params(callback1, 1, 2, 3) # This should generate an error. call_with_params(callback1, "1") # This should generate an error. call_with_params(callback2) call_with_params(callback2, 1, 1)
class A: ... class B: ... class C: ... _T3 = TypeVar("_T3", A, B, C) _P = ParamSpec("_P") _Ts = TypeVarTuple("_Ts") def func1(val1: _T1) -> _T1: if isinstance(val1, str): return "" return 0 def func2(val1: _T1) -> list[_T1]: if isinstance(val1, str): return [""] return [0] class Class1(Generic[_T1, _T2, _T3, _P, Unpack[_Ts]]):