Skip to content

PEP 718: Specify binding, parametrisation and overload interactions#4649

Merged
gvanrossum merged 14 commits intopython:mainfrom
Gobot1234:pep-718-even-more-updates
Apr 23, 2026
Merged

PEP 718: Specify binding, parametrisation and overload interactions#4649
gvanrossum merged 14 commits intopython:mainfrom
Gobot1234:pep-718-even-more-updates

Conversation

@Gobot1234
Copy link
Copy Markdown
Contributor

@Gobot1234 Gobot1234 commented Oct 8, 2025

  • Change is either:
    • To a Draft PEP
    • To an Accepted or Final PEP, with Steering Council approval
    • To fix an editorial issue (markup, typo, link, header, etc)
  • PR title prefixed with PEP number (e.g. PEP 123: Summary of changes)

📚 Documentation preview 📚: https://pep-previews--4649.org.readthedocs.build/

@Gobot1234 Gobot1234 requested a review from gvanrossum as a code owner October 8, 2025 15:10
@python-cla-bot
Copy link
Copy Markdown

python-cla-bot Bot commented Oct 8, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

@Gobot1234
Copy link
Copy Markdown
Contributor Author

Gobot1234 commented Oct 8, 2025

Please can someone get the CLA bot to re-run? I'm not sure why it's requesting that email TBH. I've already signed it for my email gobot1234yt@gmail.com

Sorry I can't test I can't get make installed
@defjaf
Copy link
Copy Markdown

defjaf commented Oct 8, 2025

I don't think that the word "subscription" is being used correctly.

@hugovk
Copy link
Copy Markdown
Member

hugovk commented Oct 8, 2025

Please can someone get the CLA bot to re-run? I'm not sure why it's requesting that email TBH. I've already signed it for my email gobot1234yt@gmail.com

You committed with your Git client configured with that email, see https://github.com/python/peps/pull/4649.patch

You also need to sign it with that.

Comment thread peps/pep-0718.rst Outdated
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.
Overloaded functions should work much the same as they already do, since they do not
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is about the runtime behavior of calling overloaded functions?

Comment thread peps/pep-0718.rst Outdated
of overloads/unions.
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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth spelling out in detail how this would work. What I'd expect is that if the function is subscripted, only those overloads are considered for which the subscription may succeed. So if you have an overload make[*Ts], one with make[T], and one with just make, then a call to make[int] will only consider the first and second, and a call to make[int, str] will only consider the first. This could be another step in the overload resolution spec before all the current steps.

Comment thread peps/pep-0718.rst Outdated
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

PabloRuizCuevas commented Nov 4, 2025

@Gobot1234 please if you need help don't hesitate to ask, I'm very interested on this feature and would be a pity to see it abandoned

@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

@JelleZijlstra Is there something I can do to move the needle on this PEP if the original author don't reply in a reasonable amount of time? like contributing to the writing of this PEP?

@JelleZijlstra
Copy link
Copy Markdown
Member

@Gobot1234 is still around, I'd wait a bit longer. But this PEP has been sitting for a long time and as I've written on Discuss before, I personally have some reservations about it. If you're interested in renewing the discussion and addressing the concerns that have been raised about the PEP, you could work with James to improve the PEP, or even write your own replacement PEP.

@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

@JelleZijlstra I already wrote James in Discourse, in GitHub and in private offering my help on September, after that he did reappear (but didn't particularly requested my help).

Now is almost a month without updates from him and I would really like to see this coming in python 3.15 (if is approved etc ofc), given that he did vanish for more than a year last time (look in discourse the message of Guido on 7 May 2023), I think is reasonable to move forward with the PEP after almost a month without updates from him. So how can I do my own PEP replacement / edit this? Would I count with your sponsorship or the original one from @gvanrossum ?

thanks in advance

@JelleZijlstra
Copy link
Copy Markdown
Member

You'd need a new sponsor. I'm not currently interested in sponsoring a version of this PEP, but another core dev might be.

@Gobot1234
Copy link
Copy Markdown
Contributor Author

@PabloRuizCuevas I'm happy to review stuff for it and would happily add you as a co-author. I just don't really have the time/motivation to finish it as my usage of python is so little nowadays

@gvanrossum
Copy link
Copy Markdown
Member

Alas, I can't take on sponsoring a new PEP either. But I will continue to fulfill my promises on the old one.

As a sponsor, I have to ask: what are the chances that the Typing Council will approve this PEP? That's the first and most important hurdle for typing PEPs.

@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

Ok I will help @Gobot1234 on finishing this one, @JelleZijlstra answering the concerns of Guido, and given that you belong to the typing council (right?), do you think that this PEP has any chance of being approved? If there is chances what would be the priority changes for me to make to advance on it. thanks in advance.

I guess the overload resolution as you already pointed out is one of them, right? anything else? I was planning to add other examples, motivations and ideas that were mentioned in discourse.

@JelleZijlstra
Copy link
Copy Markdown
Member

I don't know what the Typing Council will decide but I wrote this last year: https://discuss.python.org/t/pep-718-subscriptable-functions/28457/38 and still feel the motivation for the PEP is weak.

@hugovk
Copy link
Copy Markdown
Member

hugovk commented Feb 25, 2026

Lint is failing but the logs have expired. I've updated from main to get a fresh run.

Where are we up to with this PEP?

Reminder that the 3.15 feature freeze of 2026-05-05 is drawing near, and before this, the PEP will need:

  • to be finished
  • sent to the Typing Council for a recommendation
  • sent to the Steering Council for a decision
  • implemented and merged into CPython

Otherwise 3.16 is always an option.

@Gobot1234 Gobot1234 requested a review from JelleZijlstra March 5, 2026 11:22
@Gobot1234
Copy link
Copy Markdown
Contributor Author

@gvanrossum @JelleZijlstra would one of you mind reviewing this when you get the chance :)

I'm not really expecting it to make the 3.15 cut off but I'd still like to carry on moving forward with this.

Copy link
Copy Markdown
Member

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments. As before I find a lot of the use cases dubious so I'm not the best person to advocate for this change.

Comment thread peps/pep-0718.rst Outdated
Comment thread peps/pep-0718.rst
Comment thread peps/pep-0718.rst Outdated
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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What else should type checkers do? Infer Literal[0]?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume @JelleZijlstra meant "What else could type checkers do?" I guess another option would be Any if the binding is done as soon as C.cls is seen (C not subscripted). Also if T had a default it could legally be used in preference over inferring from the call? (I'm fuzzy about this myself.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread peps/pep-0718.rst Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you'd write foo[int](b"hello") it would also type check, right? So this is inherently unsound.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this isn't a good motivational example. The bytes | Sequence[int] and str | Sequence[str] ambiguities need solutions elsewhere (and I don't know how I'd do it).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why, though, what I care in this example is being able to control the exit type, sometimes is not possible because the argument matches type in two different ways, but this gives back control to the exit type.

but if it adds confusion, let's remove the example.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i remove it from my pr, let me know if after reading this we want to recover it.

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Copy link
Copy Markdown
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Despite leaving a bunch of comments, I would be okay with merging this now so readers of the PEP have a newer version available, and split hairs in a follow-up PR. (PRs are cheap.)

Comment thread peps/pep-0718.rst
Comment thread peps/pep-0718.rst Outdated

.. code-block:: python

def my_list[T](arr) -> list[T]:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be augmented with arr: Iterable[T] (which reflects what list(arr) expects) or is that a distraction?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing

Comment thread peps/pep-0718.rst Outdated
def make_list[T](*args: T) -> list[T]: ...
reveal_type(make_list()) # type checker cannot infer a meaningful type for T
class my_list[T]:
def __call__(self, *args: T) -> list[T]:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, this signature is inconsistent with make_list(arr) above.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment thread peps/pep-0718.rst
Comment thread peps/pep-0718.rst Outdated
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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, it's verbose when the intention is to pass the specialized value into another call -- now the reader has to deal with the distraction of seeing a temporary variable declaration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Comment thread peps/pep-0718.rst Outdated
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.
This PEP opens the door to overloading based on type variables:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the complexity and ambiguity already present in @overload I'm not sure that "opens the door" is enough of a specification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing to "this pep allows"

Comment thread peps/pep-0718.rst Outdated
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>`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That reason is so simple to explain that I'd just repeat it here. Also make it explicit that spam is acceptable here (rather than waiting to show it in the example below).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread peps/pep-0718.rst Outdated

Binding Rules
^^^^^^^^^^^^^
Method subscription (including ``classmethods``, ``staticmethods``, etc.) should only
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is covered by the casual "etc." here? In a spec it need to specified, not left as a guess for the reader based on an example.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i will plainly remove the "etc". "@Property" is not in the same box, and other decorators seem irrelevant for the matter.

Comment thread peps/pep-0718.rst Outdated
Binding Rules
^^^^^^^^^^^^^
Method subscription (including ``classmethods``, ``staticmethods``, etc.) should only
have access to their function's type parameter and not the enclosing class's.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
have access to their function's type parameter and not the enclosing class's.
allow their function's type parameters and not the enclosing class's.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modified

Comment thread peps/pep-0718.rst Outdated
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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume @JelleZijlstra meant "What else could type checkers do?" I guess another option would be Any if the binding is done as soon as C.cls is seen (C not subscripted). Also if T had a default it could legally be used in preference over inferring from the call? (I'm fuzzy about this myself.)

@gvanrossum
Copy link
Copy Markdown
Member

@Gobot1234 Let me know your preference about how to proceed. I can promise to quickly merge what you have (including my suggestion) -- I can't promise to do another big review soon.

FWIW After a conversation with Claude I'm feeling more and more confident that we should do this. The counter-arguments "you don't need this" and "you can already do this with other means" don't convince me it's a bad idea.

@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

Happy to see this moving again. @Gobot1234 let me know if you need my help addressing any of the comments

Copy link
Copy Markdown
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PabloRuizCuevas You could start by addressing the comments that Jelle and I added.

Do you need @Gobot1234's approval before you make changes to the PR?

@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

@gvanrossum unfortunately I can't merge directly, but I still went ahead and addressed all the comments in a pr to gobots branch Gobot1234#2

@Gobot1234 you can merge it if you have a moment.

Thanks both.

@PabloRuizCuevas
Copy link
Copy Markdown
Contributor

@Gobot1234 thanks! @gvanrossum your requested changes are merged

Copy link
Copy Markdown
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Will merge now!

@gvanrossum gvanrossum merged commit 17dcc42 into python:main Apr 23, 2026
4 of 5 checks passed
@gvanrossum
Copy link
Copy Markdown
Member

Merged, despite grumblings from RtD build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants