Skip to content

Commit

Permalink
PEP 696: some suggestions to make the text clearer (python#3641)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
3 people committed Feb 8, 2024
1 parent 67c0d14 commit 2b91368
Showing 1 changed file with 29 additions and 23 deletions.
52 changes: 29 additions & 23 deletions peps/pep-0696.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
~~~~~~~~~~~~~
Expand All @@ -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)
Expand All @@ -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
~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -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.

::

Expand Down Expand Up @@ -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
-------------

Expand Down

0 comments on commit 2b91368

Please sign in to comment.