PEP 696: Replace usages of TypeVarLike with type parameter (#3619)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
parent
e31c0d565e
commit
27ed905918
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue