PEP 696: some suggestions to make the text clearer (#3641)

* Moves TypeVarTuple discussion so the text flows better. Otherwise, it
  feels to me like an awkward interlude between the paragraph
  introducing rules and the actual rules.
* In sections where the text uses `T1` and `T2` as TypeVar names, changes
  the examples to use the same names.
* Fix subtyping relationship in "Bound Rules."
* Spell out subclassing rules in the text, rather than leaning so much on the example.

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: James Hilton-Balfe <gobot1234yt@gmail.com>
This commit is contained in:
Rebecca Chen 2024-02-07 16:29:44 -08:00 committed by GitHub
parent 67c0d14227
commit 2b913684ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 29 additions and 23 deletions

View File

@ -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[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__ 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. When using a type parameter as the default to another type parameter, the
Where ``T1`` is the default for ``T2`` the following rules apply. following rules apply, where ``T1`` is the default for ``T2``.
``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``.
Scoping Rules 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[T1, T2]): ... # Valid
class Foo(Generic[T]): class Foo(Generic[T1]):
class Bar(Generic[DefaultT]): ... # Valid class Bar(Generic[T2]): ... # Valid
StartT = TypeVar("StartT", default="StopT") # Swapped defaults around from previous example StartT = TypeVar("StartT", default="StopT") # Swapped defaults around from previous example
StopT = TypeVar("StopT", default=int) 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 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) T1 = TypeVar("T1", bound=int)
TypeVar("Ok", default=T, bound=int) # Valid TypeVar("Ok", default=T1, bound=float) # Valid
TypeVar("AlsoOk", default=T, bound=float) # Valid TypeVar("AlsoOk", default=T1, bound=int) # Valid
TypeVar("Invalid", default=T, bound=str) # Invalid: str is not a subtype of float TypeVar("Invalid", default=T1, bound=str) # Invalid: int is not a subtype of str
Constraint Rules Constraint Rules
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -329,7 +318,10 @@ Subclassing
''''''''''' '''''''''''
Subclasses of ``Generic``\ s with type parameters that have defaults 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] # Ts = (int, str), P = [float, bool]
Foo[int, str, [bytes]] # Ts = (int, str), P = [bytes] 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 Binding rules
------------- -------------