From a33030f405b130706371358e5b5825c5626d80e7 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Wed, 8 Oct 2025 16:08:37 +0100 Subject: [PATCH 01/12] hopefully final round of changes --- peps/pep-0718.rst | 72 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 13b4ccc1f9c..1d661f0122d 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -202,9 +202,75 @@ Interactions with ``@typing.overload`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Overloaded functions should work much the same as already, since they have no effect on -the runtime type. The only change is that more situations will be decidable and the -behaviour/overload can be specified by the developer rather than leaving it to ordering -of overloads/unions. +the runtime type. This change will lead to more expressiveness with user's able to +decide and the behaviour/overload can be specified by the developer rather than leaving +it to ordering of overloads/unions. + +.. code-block:: python + + # N.B. `class bytes(Sequence[int]): ...` and `Foo` is a non-specified generic type + @overload + def seq_first[T: Sequence[int]](x: T) -> T: ... + @overload + def seq_first[T: bytes](x: T) -> Foo[T]: ... + + @overload + def bytes_first[T: bytes](x: T) -> Foo[T]: ... + @overload + def bytes_first[T: Sequence[int]](x: T) -> T: ... + + reveal_type(seq_first(b"")) # type is bytes + reveal_type(bytes_first(b"")) # type is Foo[bytes] + +Explicit specialisation will restrict the set of available overloads + +.. code-block:: python + + @overload + def make[T](x: T) -> T: ... + @overload + def make(x: str, y: str) -> tuple[int, int]: ... + + reveal_type(make[int](1)) # type is int + reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x:str, y: str)` found, a similar overload exists but explicit specialisation prevented its use + +Functions Parameterized by ``TypeVarTuple``s +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Currently type checkers disallow the use of multiple ``TypeVarTuple``s in it's generic +parameters, however it is currently valid to have a function as such + +.. code-block:: python + + def foo[*T, *U](bar: Bar[*T], baz: Baz[*U]): ... + def spam[*T](bar: Bar[*T]): ... + +This PEP does not allow similar functions to be subscripted, for the same reason as +defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. + +.. code-block:: python + + foo[int, str, bool, complex](Bar(), Baz()) # Invalid: cannot determine which parameters are passed to *T and *U. Explicitly parameterise the instances individually + spam[int, str, bool, complex](Bar()) # OK + + +Binding Rules +^^^^^^^^^^^^^ +Subscriptions on methods (including classmethods, staticmethods etc.) should only have +access to their function's type parameters and not the enclosing class's. Subscription +should follow the rules specified in :pep:`PEP 696<696#binding-rules>` methods should +be bound on attribute access. + +.. code-block:: python + + class C[T]: + def method[U](self, x: T, y: U): ... + @classmethod + def cls[U](cls, x: T, y: U): ... + + C[int].method[str](0, "") # OK + C[int].cls[str](0, "") # OK + C.cls[int, str](0, "") # Invalid: too many type parameters + C.cls[str](0, "") # OK, T is ideally bound to int here though this is open for type checkers to decide Backwards Compatibility ----------------------- From 475bd8ee430c19d0f989870b23974ae0a6077877 Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Wed, 8 Oct 2025 16:22:39 +0100 Subject: [PATCH 02/12] I think fix the build issues? Sorry I can't test I can't get make installed --- peps/pep-0718.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 1d661f0122d..d75bdb6ecc8 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -234,10 +234,10 @@ Explicit specialisation will restrict the set of available overloads reveal_type(make[int](1)) # type is int reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x:str, y: str)` found, a similar overload exists but explicit specialisation prevented its use -Functions Parameterized by ``TypeVarTuple``s -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Currently type checkers disallow the use of multiple ``TypeVarTuple``s in it's generic -parameters, however it is currently valid to have a function as such +Functions Parameterized by ``TypeVarTuple``\ s +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Currently type checkers disallow the use of multiple ``TypeVarTuple`` \s in it's +generic parameters, however it is currently valid to have a function as such .. code-block:: python From bd36a628253920ab7892f2bedccab512ba43ba22 Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Wed, 8 Oct 2025 16:52:39 +0100 Subject: [PATCH 03/12] Fix title too short --- peps/pep-0718.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index d75bdb6ecc8..6d09ebdc5dc 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -235,7 +235,7 @@ Explicit specialisation will restrict the set of available overloads reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x:str, y: str)` found, a similar overload exists but explicit specialisation prevented its use Functions Parameterized by ``TypeVarTuple``\ s -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Currently type checkers disallow the use of multiple ``TypeVarTuple`` \s in it's generic parameters, however it is currently valid to have a function as such From 1ba67e9605ebbdfa5793497e1d9c51eb911ee741 Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Wed, 8 Oct 2025 21:14:08 +0100 Subject: [PATCH 04/12] fix some grammar typos and build --- peps/pep-0718.rst | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 6d09ebdc5dc..2fef8a22397 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -201,28 +201,9 @@ The following code snippet would fail at runtime without this change as Interactions with ``@typing.overload`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Overloaded functions should work much the same as already, since they have no effect on -the runtime type. This change will lead to more expressiveness with user's able to -decide and the behaviour/overload can be specified by the developer rather than leaving -it to ordering of overloads/unions. - -.. code-block:: python - - # N.B. `class bytes(Sequence[int]): ...` and `Foo` is a non-specified generic type - @overload - def seq_first[T: Sequence[int]](x: T) -> T: ... - @overload - def seq_first[T: bytes](x: T) -> Foo[T]: ... - - @overload - def bytes_first[T: bytes](x: T) -> Foo[T]: ... - @overload - def bytes_first[T: Sequence[int]](x: T) -> T: ... - - reveal_type(seq_first(b"")) # type is bytes - reveal_type(bytes_first(b"")) # type is Foo[bytes] - -Explicit specialisation will restrict the set of available overloads +Overloaded functions should work much the same as they already do, since they do not +affect the runtime type. Explicit specialisation will restrict the set of available +overloads. .. code-block:: python @@ -232,33 +213,32 @@ Explicit specialisation will restrict the set of available overloads def make(x: str, y: str) -> tuple[int, int]: ... reveal_type(make[int](1)) # type is int - reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x:str, y: str)` found, a similar overload exists but explicit specialisation prevented its use + reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x: str, y: str)` found, a similar overload exists but explicit specialisation prevented its use Functions Parameterized by ``TypeVarTuple``\ s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Currently type checkers disallow the use of multiple ``TypeVarTuple`` \s in it's -generic parameters, however it is currently valid to have a function as such +Currently, type checkers disallow the use of multiple ``TypeVarTuple``\s in their +generic parameters; however, it is currently valid to have a function as such: .. code-block:: python def foo[*T, *U](bar: Bar[*T], baz: Baz[*U]): ... def spam[*T](bar: Bar[*T]): ... -This PEP does not allow similar functions to be subscripted, for the same reason as -defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. +This PEP does not allow functions like ``foo`` to be subscripted, for the same reason +as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. .. code-block:: python foo[int, str, bool, complex](Bar(), Baz()) # Invalid: cannot determine which parameters are passed to *T and *U. Explicitly parameterise the instances individually spam[int, str, bool, complex](Bar()) # OK - Binding Rules ^^^^^^^^^^^^^ -Subscriptions on methods (including classmethods, staticmethods etc.) should only have -access to their function's type parameters and not the enclosing class's. Subscription -should follow the rules specified in :pep:`PEP 696<696#binding-rules>` methods should -be bound on attribute access. +Method subscription (including ``classmethods``, ``staticmethods``, etc.) should only +have access tos their function's type parameter and not the enclosing class's. +Subscription should follow the rules specified in :pep:`PEP 696<696#binding-rules>`; +methods should bind type parameters on attribute access. .. code-block:: python From 4d33729b1a7bb14e66b71a500bc2a8b9e6275d49 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Tue, 14 Oct 2025 10:48:38 +0100 Subject: [PATCH 05/12] Update peps/pep-0718.rst Co-authored-by: Jelle Zijlstra --- peps/pep-0718.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 2fef8a22397..d9fbccff3e0 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -236,7 +236,7 @@ as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. Binding Rules ^^^^^^^^^^^^^ Method subscription (including ``classmethods``, ``staticmethods``, etc.) should only -have access tos their function's type parameter and not the enclosing class's. +have access to their function's type parameter and not the enclosing class's. Subscription should follow the rules specified in :pep:`PEP 696<696#binding-rules>`; methods should bind type parameters on attribute access. From 6ac59ebf55200084bf02bc9c5fb259dc8d6d05fd Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Thu, 5 Mar 2026 11:20:43 +0000 Subject: [PATCH 06/12] final round of changes --- peps/pep-0718.rst | 156 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 123 insertions(+), 33 deletions(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index d9fbccff3e0..11259cff19b 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -1,6 +1,6 @@ PEP: 718 Title: Subscriptable functions -Author: James Hilton-Balfe +Author: James Hilton-Balfe , Pablo Ruiz Cuevas Sponsor: Guido van Rossum Discussions-To: https://discuss.python.org/t/28457/ Status: Draft @@ -17,41 +17,113 @@ This PEP proposes making function objects subscriptable for typing purposes. Doi gives developers explicit control over the types produced by the type checker where bi-directional inference (which allows for the types of parameters of anonymous functions to be inferred) and other methods than specialisation are insufficient. It -also brings functions in line with regular classes in their ability to be -subscriptable. +also makes functions consistent with regular classes in their ability to be +subscripted. Motivation ---------- -Unknown Types -^^^^^^^^^^^^^ +Currently, classes allow passing type annotations for generic containers, this +is especially useful in common constructors such as ``list``\, ``tuple`` and ``dict`` +etc. -Currently, it is not possible to infer the type parameters to generic functions in -certain situations: +.. code-block:: python + + my_integer_list = list[int]() + reveal_type(my_integer_list) # type is list[int] + +At runtime ``list[int]`` returns a ``GenericAlias`` that can be later called, returning +an empty list. + +Another example of this is creating a specialised ``dict`` type for a section of our +code where we want to ensure that keys are ``str`` and values are ``int``: + +.. code-block:: python + + NameNumberDict = dict[str, int] + + NameNumberDict( + one=1, + two=2, + three="3" # Invalid: Literal["3"] is not of type int + ) + +In spite of the utility of this syntax, when trying to use it with a function, an error +is raised, as functions are not subscriptable. + +.. code-block:: python + + def my_list[T](arr) -> list[T]: + # do something... + return list(arr) + + my_integer_list = my_list[int]() # TypeError: 'function' object is not subscriptable + +There are a few workarounds: + +1. Making a callable class: + +.. code-block:: python + + class my_list[T]: + def __call__(self, *args: T) -> list[T]: + # do something... + return list(args) + +2. Using :pep:`747`\'s TypeForm, with an extra unused argument: + +.. code-block:: python + + from typing import TypeForm + + def my_list(*args: T, typ: TypeForm[T]) -> list[T]: + # do something... + return list(args) + +As we can see this solution increases the complexity with an extra argument. +Additionally it requires the user to understand a new concept ``TypeForm``. + +3. Annotating the assignment: .. code-block:: python - def make_list[T](*args: T) -> list[T]: ... - reveal_type(make_list()) # type checker cannot infer a meaningful type for T + my_integer_list: list[int] = my_list() + +This solution isn't optimal as the return type is repeated and is more verbose and +would require the type updating in multiple places if the return type changes. + +In conclusion, the current workarounds are too complex or verbose, especially compared +to syntax that is consistent with the rest of the language. -Making instances of ``FunctionType`` subscriptable would allow for this constructor to -be typed: +Generic Specialisation +^^^^^^^^^^^^^^^^^^^^^^ + +As in the previous example currently we can create generic aliases for different +specialised usages: .. code-block:: python - reveal_type(make_list[int]()) # type is list[int] + NameNumberDict = dict[str, int] + NameNumberDict(one=1, two=2, three="3") # Invalid: Literal["3"] is not of type int`` -Currently you have to use an assignment to provide a precise type: +This not currently possible for functions but if allowed we could easily +specialise operations in certain sections of the codebase: .. code-block:: python - x: list[int] = make_list() - reveal_type(x) # type is list[int] + def constrained_addition[T](a: T, b: T) -> T: ... -but this code is unnecessarily verbose taking up multiple lines for a simple function -call. + # where we work exclusively with ints + int_addition = constrained_addition[int] + int_addition(2, 4+8j) # Invalid: complex is not of type int -Similarly, ``T`` in this example cannot currently be meaningfully inferred, so ``x`` is +Unknown Types +^^^^^^^^^^^^^ + +Currently, it is not possible to infer the type parameters to generic functions in +certain situations. + +In this example ``T`` cannot currently be meaningfully inferred, so ``x`` is untyped without an extra assignment: .. code-block:: python @@ -66,11 +138,11 @@ If function objects were subscriptable, however, a more specific type could be g reveal_type(factory[int](lambda x: "Hello World" * x)) # type is Foo[int] -Undecidable Inference -^^^^^^^^^^^^^^^^^^^^^ +Undecidable Inference and Type Narrowing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -There are even cases where subclass relations make type inference impossible. However, -if you can specialise the function type checkers can infer a meaningful type. +There are cases where subclass relations make type inference impossible. However, if +you can specialise the function type checkers can infer a meaningful type. .. code-block:: python @@ -138,7 +210,16 @@ The syntax for such a feature may look something like: Rationale --------- -Function objects in this PEP is used to refer to ``FunctionType``\ , ``MethodType``\ , +This proposal improves the consistency of the type system, by allowing syntax that +already looks and feels like a natural of the existing syntax for classes. + +If accepted, this syntax will reduce the necessity to learn about :pep:`747`\s +``TypeForm``, reduce verbosity and cognitive load of safely typed python. + +Specification +------------- + +In this PEP "Function objects" is used to refer to ``FunctionType``\ , ``MethodType``\ , ``BuiltinFunctionType``\ , ``BuiltinMethodType`` and ``MethodWrapperType``\ . For ``MethodType`` you should be able to write: @@ -161,9 +242,6 @@ functions implemented in Python as possible. ``MethodWrapperType`` (e.g. the type of ``object().__str__``) is useful for generic magic methods. -Specification -------------- - Function objects should implement ``__getitem__`` to allow for subscription at runtime and return an instance of ``types.GenericAlias`` with ``__origin__`` set as the callable and ``__args__`` as the types passed. @@ -201,19 +279,31 @@ The following code snippet would fail at runtime without this change as Interactions with ``@typing.overload`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Overloaded functions should work much the same as they already do, since they do not -affect the runtime type. Explicit specialisation will restrict the set of available -overloads. +This PEP opens the door to overloading based on type variables: .. code-block:: python @overload - def make[T](x: T) -> T: ... + def serializer_for[T: str]() -> StringSerializer: ... @overload - def make(x: str, y: str) -> tuple[int, int]: ... + def serializer_for[T: list]() -> ListSerializer: ... + + def serializer_for(): + ... + +For overload resolution a new step will be required previous to any other, where the resolver +will match only the overloads where the subscription may succeed. + +.. code-block:: python + + @overload + def make[*Ts]() -> float: ... + @overload + def make[T]() -> int: ... + + make[int] # matches first and second overload + make[int, str] # matches only first - reveal_type(make[int](1)) # type is int - reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x: str, y: str)` found, a similar overload exists but explicit specialisation prevented its use Functions Parameterized by ``TypeVarTuple``\ s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From c6b45888157dda55a95f6cc7ee925c206dca4dcc Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 20 Apr 2026 12:51:39 -0700 Subject: [PATCH 07/12] Split long sentence in two for style Co-authored-by: Jelle Zijlstra --- peps/pep-0718.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 11259cff19b..daacb0874d7 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -23,7 +23,7 @@ subscripted. Motivation ---------- -Currently, classes allow passing type annotations for generic containers, this +Currently, classes allow passing type annotations for generic containers. This is especially useful in common constructors such as ``list``\, ``tuple`` and ``dict`` etc. From 382eb92d1ee66e9e26cb393de24d7308bc3e9073 Mon Sep 17 00:00:00 2001 From: Pablo <48098178+PabloRuizCuevas@users.noreply.github.com> Date: Wed, 22 Apr 2026 21:38:34 +0700 Subject: [PATCH 08/12] Update pep-0718.rst Adresed @gvanrossum comments --- peps/pep-0718.rst | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index daacb0874d7..36790365d01 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -53,7 +53,7 @@ is raised, as functions are not subscriptable. .. code-block:: python - def my_list[T](arr) -> list[T]: + def my_list[T](arr: Iterable[T]) -> list[T]: # do something... return list(arr) @@ -66,9 +66,11 @@ There are a few workarounds: .. code-block:: python class my_list[T]: - def __call__(self, *args: T) -> list[T]: + def __call__(self, arr: Iterable[T]) -> list[T]: # do something... - return list(args) + return list(arr) + + my_string_list = my_list[str]([]) 2. Using :pep:`747`\'s TypeForm, with an extra unused argument: @@ -76,9 +78,11 @@ There are a few workarounds: from typing import TypeForm - def my_list(*args: T, typ: TypeForm[T]) -> list[T]: + def my_list(*arr: Iterable[T], typ: TypeForm[T]) -> list[T]: # do something... - return list(args) + return list(arr) + + my_string_list = my_list([], str) As we can see this solution increases the complexity with an extra argument. Additionally it requires the user to understand a new concept ``TypeForm``. @@ -89,8 +93,7 @@ Additionally it requires the user to understand a new concept ``TypeForm``. my_integer_list: list[int] = my_list() -This solution isn't optimal as the return type is repeated and is more verbose and -would require the type updating in multiple places if the return type changes. +This solution isn't optimal as the return type is repeated, is more verbose and would require the type updating in multiple places if the return type changes. Additionally, it adds unnecesary and distracting verbossity when the intention is to pass the specialized value into another call. In conclusion, the current workarounds are too complex or verbose, especially compared to syntax that is consistent with the rest of the language. @@ -130,7 +133,7 @@ untyped without an extra assignment: def factory[T](func: Callable[[T], Any]) -> Foo[T]: ... - reveal_type(factory(lambda x: "Hello World" * x)) + reveal_type(factory(lambda x: "Hello World" * x)) # type is Foo[Unknown] If function objects were subscriptable, however, a more specific type could be given: @@ -138,20 +141,6 @@ If function objects were subscriptable, however, a more specific type could be g reveal_type(factory[int](lambda x: "Hello World" * x)) # type is Foo[int] -Undecidable Inference and Type Narrowing -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -There are cases where subclass relations make type inference impossible. However, if -you can specialise the function type checkers can infer a meaningful type. - -.. code-block:: python - - def foo[T](x: Sequence[T] | T) -> list[T]: ... - - reveal_type(foo[bytes](b"hello")) - -Currently, type checkers do not consistently synthesise a type here. - Unsolvable Type Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +268,7 @@ The following code snippet would fail at runtime without this change as Interactions with ``@typing.overload`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This PEP opens the door to overloading based on type variables: +This PEP will also allow type checkers to do overloading based on type variables: .. code-block:: python @@ -316,7 +305,7 @@ generic parameters; however, it is currently valid to have a function as such: def spam[*T](bar: Bar[*T]): ... This PEP does not allow functions like ``foo`` to be subscripted, for the same reason -as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. +as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`, the type variables cannot be resolved unambiguously with the current syntax. .. code-block:: python @@ -325,8 +314,8 @@ as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. Binding Rules ^^^^^^^^^^^^^ -Method subscription (including ``classmethods``, ``staticmethods``, etc.) should only -have access to their function's type parameter and not the enclosing class's. +Method subscription (including ``classmethods`` and ``staticmethods``), should only +allow their function's type parameters and not the enclosing class's. Subscription should follow the rules specified in :pep:`PEP 696<696#binding-rules>`; methods should bind type parameters on attribute access. @@ -340,7 +329,7 @@ methods should bind type parameters on attribute access. C[int].method[str](0, "") # OK C[int].cls[str](0, "") # OK C.cls[int, str](0, "") # Invalid: too many type parameters - C.cls[str](0, "") # OK, T is ideally bound to int here though this is open for type checkers to decide + C.cls[str](0, "") # OK, U will be matched to str Backwards Compatibility ----------------------- From 3baa5be869f908d7707106bf422f666d3deddc71 Mon Sep 17 00:00:00 2001 From: Pablo <48098178+PabloRuizCuevas@users.noreply.github.com> Date: Wed, 22 Apr 2026 21:48:54 +0700 Subject: [PATCH 09/12] Update pep-0718.rst Small change --- peps/pep-0718.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 36790365d01..35077627594 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -268,7 +268,7 @@ The following code snippet would fail at runtime without this change as Interactions with ``@typing.overload`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This PEP will also allow type checkers to do overloading based on type variables: +This PEP allows type checkers to do overloading based on type variables: .. code-block:: python From 83116223f4fcec4c6f558316523ff757a4336a08 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Thu, 23 Apr 2026 09:08:29 +0100 Subject: [PATCH 10/12] fix line wrap --- peps/pep-0718.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 35077627594..802f7858542 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -93,7 +93,10 @@ Additionally it requires the user to understand a new concept ``TypeForm``. my_integer_list: list[int] = my_list() -This solution isn't optimal as the return type is repeated, is more verbose and would require the type updating in multiple places if the return type changes. Additionally, it adds unnecesary and distracting verbossity when the intention is to pass the specialized value into another call. +This solution isn't optimal as the return type is repeated, is more verbose and would +require the type updating in multiple places if the return type changes. Additionally, +it adds unnecesary and distracting verbossity when the intention is to pass the +specialized value into another call. In conclusion, the current workarounds are too complex or verbose, especially compared to syntax that is consistent with the rest of the language. From 75ca1adecaa27697f00efeee714b8355e8802ec9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 08:08:49 +0000 Subject: [PATCH 11/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- peps/pep-0718.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 802f7858542..2ef41ad1dbb 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -95,7 +95,7 @@ Additionally it requires the user to understand a new concept ``TypeForm``. This solution isn't optimal as the return type is repeated, is more verbose and would require the type updating in multiple places if the return type changes. Additionally, -it adds unnecesary and distracting verbossity when the intention is to pass the +it adds unnecesary and distracting verbossity when the intention is to pass the specialized value into another call. In conclusion, the current workarounds are too complex or verbose, especially compared From 109fddd3062f22c715455c3dad8411748b1e6602 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Thu, 23 Apr 2026 09:10:43 +0100 Subject: [PATCH 12/12] more line wrap --- peps/pep-0718.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/peps/pep-0718.rst b/peps/pep-0718.rst index 2ef41ad1dbb..7b1ef5d0442 100644 --- a/peps/pep-0718.rst +++ b/peps/pep-0718.rst @@ -308,7 +308,8 @@ generic parameters; however, it is currently valid to have a function as such: def spam[*T](bar: Bar[*T]): ... This PEP does not allow functions like ``foo`` to be subscripted, for the same reason -as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`, the type variables cannot be resolved unambiguously with the current syntax. +as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`, the type +variables cannot be resolved unambiguously with the current syntax. .. code-block:: python