PEP 0646 – Variadic Generics (GAFA people)

Authors

  • Mark Mendoza <mendoza.mark.a at gmail.com>,

  • Matthew Rahtz <mrahtz at google.com>,

  • Pradeep Kumar Srinivasan <gohanpra at gmail.com>,

  • Vincent Siles <vsiles at fb.com>

Variadic Generics example 1

from typing import Generic, Tuple, TypeVar, TypeVarTuple

TPacket = TypeVar("TPacket")
TFields = TypeVar("TFields")

class Packet(Generic[TPacket, *TFields]):
    def __init__(self, *fields: *TFields):
        ...

    @property
    def fields(self) -> Tuple[*TFields]:
        ...

    @property
    def data(self) -> TPacket:
        ...

packet: Packet[bytes, int, str] = Packet(56, "example")
size, name = packet.fields # Tuple[int, str]
data = packet.data #bytes

Variadic generics example 2

Generics can now be variadic, supporting a variable number of arguments , using TypeVarTuple .

For example, NumPy wanted this feature to indicate the sizes and dimensions of an array.

Here’s a quick example from PEP 646

from typing import Generic, TypeVar, TypeVarTuple, NewType

DType = TypeVar('DType')
Shape = TypeVarTuple('Shape')

class Array(Generic[DType, *Shape]):

    def __abs__(self) -> Array[DType, *Shape]: ...
    def __add__(self, other: Array[DType, *Shape]) -> Array[DType, *Shape]: ...


Height = NewType('Height', int)
Width = NewType('Width', int)

x: Array[float, Height, Width] = Array()