These newer features type APIs that were previously only expressible with Any, from array shapes to config kwargs.
Three newer features complete the generics toolkit.
TypeVarTuple (PEP 646, 3.11) is a type variable standing for any number of types. With 3.12 syntax: class Array[*Shape]. Then Array[int, int] and Array[int, int, int] are different types, which array libraries use to track dimensions. Functions can capture tuples: def args_to_tuple[*Ts](*args: *Ts) -> tuple[*Ts].
`Unpack[TypedDict]` for `kwargs** (PEP 692, 3.12): def connect(kwargs: Unpack[Options])` gives each keyword its own type and makes required and optional keys explicit, instead of `kwargs: Any`.
Type parameter defaults (PEP 696, 3.13): class Response[T = bytes] means a bare Response is Response[bytes] rather than Response[Any]. Old-style: TypeVar("T", default=bytes). It's useful for evolving generic classes without breaking existing annotations.
Also worth knowing for library authors: @dataclass_transform() (3.11) tells checkers that a decorator or base class generates dataclass-like __init__ methods, which is how ORMs and Pydantic get precise constructor checking.
Checker support for these lands gradually, so verify with your mypy or pyright version.
Example
from typing import NotRequired, TypedDict, Unpack
class Options(TypedDict):
host: str
port: NotRequired[int]
def connect(**kwargs: Unpack[Options]) -> str:
return f"{kwargs['host']}:{kwargs.get('port', 5432)}"
def to_tuple[*Ts](*args: *Ts) -> tuple[*Ts]:
return args
class Response[T = bytes]: # default (3.13)
def __init__(self, body: T) -> None:
self.body = body
print(connect(host="db")) # db:5432
t = to_tuple(1, "a", 2.0) # checker: tuple[int, str, float]
print(t) # (1, 'a', 2.0)
r: Response = Response(b"ok") # checker: Response[bytes]
print(Response.__type_params__[0].__default__) # <class 'bytes'>
# connect(host="db", prot=1) -> checker error: unexpected keyword "prot"Remember
- TypeVarTuple (*Ts) generalises over any number of types
- **kwargs: Unpack[TD] types each keyword argument
- Type parameter defaults (3.13) replace Any for bare generics
Watch out for
- Assuming every checker version supports the newest PEPs; check release notes before relying on them.