PEP 696: Replace usages of TypeVarLike with type parameter (#3619)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
James Hilton-Balfe 2024-02-01 15:02:03 +00:00 committed by GitHub
parent e31c0d565e
commit 27ed905918
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 25 additions and 25 deletions

View File

@ -1,5 +1,5 @@
PEP: 696
Title: Type defaults for TypeVarLikes
Title: Type Defaults for Type Parameters
Author: James Hilton-Balfe <gobot1234yt@gmail.com>
Sponsor: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Discussions-To: https://discuss.python.org/t/pep-696-type-defaults-for-typevarlikes/22569
@ -15,8 +15,8 @@ Post-History: `22-Mar-2022 <https://mail.python.org/archives/list/typing-sig@pyt
Abstract
--------
This PEP introduces the concept of type defaults for
``TypeVarLike``\ s (``TypeVar``, ``ParamSpec`` and ``TypeVarTuple``),
This PEP introduces the concept of type defaults for type parameters,
including ``TypeVar``, ``ParamSpec``, and ``TypeVarTuple``,
which act as defaults for a type parameter when one is not specified or
the constraint solver isn't able to solve a type parameter to anything.
@ -93,7 +93,7 @@ Default Ordering and Subscription Rules
'''''''''''''''''''''''''''''''''''''''
The order for defaults should follow the standard function parameter
rules, so a ``TypeVarLike`` with no ``default`` cannot follow one with
rules, so a type parameter with no ``default`` cannot follow one with
a ``default`` value. Doing so should ideally raise a ``TypeError`` in
``typing._GenericAlias``/``types.GenericAlias``, and a type checker
should flag this an error.
@ -175,15 +175,15 @@ or another in-scope ``TypeVarTuple`` (see `Scoping Rules`_).
reveal_type(Foo()) # type is Foo[str, int]
reveal_type(Foo[int, bool]()) # type is Foo[int, bool]
Using Another ``TypeVarLike`` as ``default``
Using Another Type Parameter as ``default``
''''''''''''''''''''''''''''''''''''''''''''
This allows for a value to be used again when the constraints solver
fails to solve a constraint for a type, or the type parameter to a
generic is missing but another type parameter is specified.
To use another ``TypeVarLike`` as a default the ``default`` and the
``TypeVarLike`` must be the same type (a ``TypeVar``'s default must be
To use another type parameter as a default the ``default`` and the
type parameter must be the same type (a ``TypeVar``'s default must be
a ``TypeVar``, etc.).
`This could be used on builtins.slice <https://github.com/python/typing/issues/159>`__
@ -212,17 +212,17 @@ 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 ``TypeVarLike`` as the default to another ``TypeVarLike``.
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 ``TypeVarLikes``
- `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 class, as specified in
:pep:`646#multiple-type-variable-tuples-not-allowed`.
- ``TypeVarLike`` defaults in functions are not supported.
- type parameter defaults in functions are not supported.
These reasons leave no current valid location where a
``TypeVarTuple`` could have a default.
@ -245,7 +245,7 @@ Scoping Rules
class slice(Generic[StartT, StopT, StepT]): ...
# ^^^^^^ Invalid: ordering does not allow StopT to be bound
Using a ``TypeVarLike`` from an outer scope as a default is not supported.
Using a type parameter from an outer scope as a default is not supported.
Bound Rules
~~~~~~~~~~~
@ -274,10 +274,10 @@ The constraints of ``T2`` must be a superset of the constraints of ``T1``.
TypeVar("AlsoInvalid", bool, complex, default=T1) # Invalid: {bool, complex} is not a superset of {int, str}
``TypeVarLike``\s as Parameters to Generics
Type Parameters as Parameters to Generics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``TypeVarLike``\ s are valid as parameters to generics inside of a
Type parameters are valid as parameters to generics inside of a
``default`` when the first parameter is in scope as determined by the
`previous section <scoping rules_>`_.
@ -298,7 +298,7 @@ The constraints of ``T2`` must be a superset of the constraints of ``T1``.
Specialisation Rules
~~~~~~~~~~~~~~~~~~~~
``TypeVarLike``\ s currently cannot be further subscripted. This might
Type parameters currently cannot be further subscripted. This might
change if `Higher Kinded TypeVars <https://github.com/python/typing/issues/548>`__
are implemented.
@ -307,7 +307,7 @@ are implemented.
'''''''''''''''''''''''''''''
``Generic`` ``TypeAlias``\ es should be able to be further subscripted
following normal subscription rules. If a ``TypeVarLike`` has a default
following normal subscription rules. If a type parameter has a default
that hasn't been overridden it should be treated like it was
substituted into the ``TypeAlias``. However, it can be specialised
further down the line.
@ -325,7 +325,7 @@ further down the line.
Subclassing
'''''''''''
Subclasses of ``Generic``\ s with ``TypeVarLike``\ s that have defaults
Subclasses of ``Generic``\ s with type parameters that have defaults
behave similarly to ``Generic`` ``TypeAlias``\ es.
.. code-block:: py
@ -378,14 +378,14 @@ subtype of one of the constraints.
Function Defaults
'''''''''''''''''
``TypeVarLike``\ s currently are not supported in the signatures of
Type parameters currently are not supported in the signatures of
functions as ensuring the ``default`` is returned in every code path
where the ``TypeVarLike`` can go unsolved is too hard to implement.
where the type parameter can go unsolved is too hard to implement.
Binding rules
-------------
``TypeVarLikes`` defaults should be bound by attribute access
Type parameter defaults should be bound by attribute access
(including call and subscript).
.. code-block:: python
@ -469,14 +469,14 @@ Grammar Changes
| '=' e=expression
| '=' e=starred_expression
This would mean that ``TypeVarLike``\ s with defaults proceeding those
This would mean that type parameters with defaults proceeding those
with non-defaults can be checked at compile time.
Rejected Alternatives
---------------------
Allowing the ``TypeVarLike``\s Defaults to Be Passed to ``type.__new__``'s ``**kwargs``
Allowing the Type Parameters Defaults to Be Passed to ``type.__new__``'s ``**kwargs``
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
.. code-block:: py
@ -535,8 +535,8 @@ Having ``default`` Implicitly Be ``bound``
In an earlier version of this PEP, the ``default`` was implicitly set
to ``bound`` if no value was passed for ``default``. This while
convenient, could have a ``TypeVarLike`` with no default follow a
``TypeVarLike`` with a default. Consider:
convenient, could have a type parameter with no default follow a
type parameter with a default. Consider:
.. code-block:: py
@ -557,7 +557,7 @@ convenient, could have a ``TypeVarLike`` with no default follow a
This would have also been a breaking change for a small number of cases
where the code relied on ``Any`` being the implicit default.
Allowing ``TypeVarLike``\s with defaults to be used in function signatures
Allowing Type Parameters With Defaults To Be Used in Function Signatures
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
A previous version of this PEP allowed ``TypeVarLike``\s with defaults to be used in
@ -565,7 +565,7 @@ function signatures. This was removed for the reasons described in
`Function Defaults`_. Hopefully, this can be added in the future if
a way to get the runtime value of a type parameter is added.
Allowing ``TypeVarLikes`` from outer scopes in ``default``
Allowing Type Parameters from Outer Scopes in ``default``
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
This was deemed too niche a feature to be worth the added complexity.