Skip to content

Make abstract/dunder methods positional-only. #135312

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

Open
randolf-scholz opened this issue Jun 9, 2025 · 2 comments
Open

Make abstract/dunder methods positional-only. #135312

randolf-scholz opened this issue Jun 9, 2025 · 2 comments
Labels
stdlib Python modules in the Lib dir topic-typing type-feature A feature request or enhancement

Comments

@randolf-scholz
Copy link
Contributor

randolf-scholz commented Jun 9, 2025

Feature or enhancement

It would be nice if certain abstract methods / dunder methods would be defined with positional-only arguments, so that when one subclasses them an appropriate name can be chosen, or they can be defined positional-only in the subclass.1

Code sample in pyright playground1

from typing import overload
from collections.abc import Sequence

class MySequence[T](Sequence[T]):
    def __len__(self): return 0
    @overload
    def __getitem__(self, idx: int, /) -> T: ...
    @overload
    def __getitem__(self, idx: slice, /) -> Sequence[T]: ...
    def __getitem__(self, idx: int | slice, /) -> T | Sequence[T]:  # ❌ override
        return MySequence[T]()

In some cases, the stubs already fake that the argument is positional-only, such as for Container.__contains__:

Personally, I think only changing the stubs would be a pragmatic choice, but I was told by the maintainers that they believe this change should be done in Cpython first.

Backward Compatibility

  1. Changing non-abstract methods can potentially break user code. For example, this is currently legal code at runtime

    from collections.abc import Container.
    Container.__subclasshook__(C=list)  # True
  2. Changing the signature of abstract methods can introduce type-checker errors Code sample in pyright playground1

    from collections.abc import Sequence
    def get(x: Sequence[float], index: int) -> float:
        return x.__getitem__(index=index)

With this in mind, I believe changing abstrac dunder methods to use positional only arguments should be relatively safe, as calling them directly with keyword is very uncommon, and at worst it will introduce type errors.

Personally, I'd also like so see methods like Container.__subclasshook__ use positional-only arguments, but I also understand if this is not feasible due to bc-conerns.

Has this already been discussed elsewhere?

python/typeshed#14071

Footnotes

  1. Note that mypy special cases certain dunder methods, and yields different results than pyright on these examples 2 3

@randolf-scholz randolf-scholz added the type-feature A feature request or enhancement label Jun 9, 2025
@randolf-scholz randolf-scholz changed the title Make dunder methods positional-only in abstract classes. Make abstract methods positional-only. Jun 9, 2025
@randolf-scholz randolf-scholz changed the title Make abstract methods positional-only. Make abstract dunder methods positional-only. Jun 9, 2025
@randolf-scholz randolf-scholz changed the title Make abstract dunder methods positional-only. Make abstract/dunder methods positional-only. Jun 9, 2025
@picnixz picnixz added stdlib Python modules in the Lib dir topic-typing labels Jun 9, 2025
@randolf-scholz
Copy link
Contributor Author

I did a scan of the collections.abc module to see how often certain methods are called with keyword arguments, here are the results.

@JelleZijlstra
Copy link
Member

This is probably fine for the dunder methods in 3.15; it technically breaks compatibility but any affected code (if any exists) is extremely questionable.

The non-dunder methods should probably also use positional-only args if we add them today, but making them positional-only now seems a bit riskier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir topic-typing type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants