Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 8 commits into from
Feb 8, 2024
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
Loading