diff --git a/peps/pep-0696.rst b/peps/pep-0696.rst index f832aa19b..4b0b22e1a 100644 --- a/peps/pep-0696.rst +++ b/peps/pep-0696.rst @@ -216,19 +216,8 @@ default to the type of ``start`` and step default to ``int | None``. Foo[int](1, "") # Invalid: Foo[int, str] cannot be assigned to self: Foo[int, int] in Foo.__init__ Foo[int]("", 1) # Invalid: Foo[str, int] cannot be assigned to self: Foo[int, int] in Foo.__init__ -When using a type parameter as the default to another type parameter. -Where ``T1`` is the default for ``T2`` the following rules apply. - -``TypeVarTuple``\s are not supported because: - -- `Scoping Rules`_ does not allow usage of type parameters - from outer scopes. -- Multiple ``TypeVarTuple``\s cannot appear in the type - parameter list for a single object, as specified in - :pep:`646#multiple-type-variable-tuples-not-allowed`. - -These reasons leave no current valid location where a -``TypeVarTuple`` could be used as the default of another ``TypeVarTuple``. +When using a type parameter as the default to another type parameter, the +following rules apply, where ``T1`` is the default for ``T2``. Scoping Rules ~~~~~~~~~~~~~ @@ -237,11 +226,11 @@ Scoping Rules :: - DefaultT = TypeVar("DefaultT", default=T) + T2 = TypeVar("T2", default=T1) - class Foo(Generic[T, DefaultT]): ... # Valid - class Foo(Generic[T]): - class Bar(Generic[DefaultT]): ... # Valid + class Foo(Generic[T1, T2]): ... # Valid + class Foo(Generic[T1]): + class Bar(Generic[T2]): ... # Valid StartT = TypeVar("StartT", default="StopT") # Swapped defaults around from previous example StopT = TypeVar("StopT", default=int) @@ -253,14 +242,14 @@ Using a type parameter from an outer scope as a default is not supported. Bound Rules ~~~~~~~~~~~ -``T2``'s bound must be a subtype of ``T1``'s bound. +``T1``'s bound must be a subtype of ``T2``'s bound. :: - T = TypeVar("T", bound=float) - TypeVar("Ok", default=T, bound=int) # Valid - TypeVar("AlsoOk", default=T, bound=float) # Valid - TypeVar("Invalid", default=T, bound=str) # Invalid: str is not a subtype of float + T1 = TypeVar("T1", bound=int) + TypeVar("Ok", default=T1, bound=float) # Valid + TypeVar("AlsoOk", default=T1, bound=int) # Valid + TypeVar("Invalid", default=T1, bound=str) # Invalid: int is not a subtype of str Constraint Rules ~~~~~~~~~~~~~~~~ @@ -329,7 +318,10 @@ Subclassing ''''''''''' Subclasses of ``Generic``\ s with type parameters that have defaults -behave similarly to ``Generic`` ``TypeAlias``\ es. +behave similarly to ``Generic`` ``TypeAlias``\ es. That is, subclasses can be +further subscripted following normal subscription rules, non-overridden +defaults should be substituted in, and type parameters with such defaults can be +further specialised down the line. :: @@ -421,6 +413,20 @@ for the ``ParamSpec`` and one for the ``TypeVarTuple``. Foo[int, str] # Ts = (int, str), P = [float, bool] Foo[int, str, [bytes]] # Ts = (int, str), P = [bytes] +``TypeVarTuple``\ s as Defaults +''''''''''''''''''''''''''''''' + +Using a ``TypeVarTuple`` as a default is not supported because: + +- `Scoping Rules`_ does not allow usage of type parameters + from outer scopes. +- Multiple ``TypeVarTuple``\ s cannot appear in the type + parameter list for a single object, as specified in + :pep:`646#multiple-type-variable-tuples-not-allowed`. + +These reasons leave no current valid location where a +``TypeVarTuple`` could be used as the default of another ``TypeVarTuple``. + Binding rules -------------