Skip to content

stdlib: Replace overload hack in operator.itemgetter by PEP 646 unpack - #11136

Merged
AlexWaygood merged 7 commits into
python:mainfrom
hamdanal:stdlib-operator-pep646
Dec 10, 2023
Merged

AlexWaygood merged 7 commits into
python:mainfrom
hamdanal:stdlib-operator-pep646

Conversation

@hamdanal

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread stdlib/_operator.pyi Outdated
@github-actions

This comment has been minimized.

Comment thread stdlib/_operator.pyi Outdated
Comment thread stdlib/_operator.pyi Outdated
Comment thread stdlib/_operator.pyi Outdated
Co-authored-by: Sebastian Rittau <srittau@rittau.biz>
Comment thread stdlib/_operator.pyi
Co-authored-by: Sebastian Rittau <srittau@rittau.biz>

@srittau srittau left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks!

Comment thread stdlib/_operator.pyi Outdated
@hamdanal

Copy link
Copy Markdown
Contributor Author

attrgetter also accepts a keyword attr in the stub but the C implementation only take positional arguments

$ python -c 'import operator; operator.attrgetter(attr="a")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: attrgetter() takes no keyword arguments

Should I send a PR fixing it?

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@AlexWaygood AlexWaygood left a comment

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.

Thanks, this looks good -- I left an inline comment about one more nit, though it doesn't really matter that much.

In general, I'm slightly confused about why we're bothering to make this class generic at all, actually. It doesn't seem like it being generic really does much for us; it's not really possible to express the semantics of this class properly right now, with our current type system. But hey.

Comment thread stdlib/_operator.pyi Outdated
@AlexWaygood

AlexWaygood commented Dec 10, 2023

Copy link
Copy Markdown
Member

Maybe the best way to type this class would be to do something like this:

_T = TypeVar("_T")
_R = TypeVar("_R")
_T1 = TypeVar("_T1")
_T2 = TypeVar("_T2")
_T3 = TypeVar("_T3")
_T4 = TypeVar("_T4")
_T5 = TypeVar("_T5")
_Ts = TypeVarTuple("_Ts")
_Ts1 = TypeVarTuple("_Ts1")

@final
class itemgetter(Generic[_T, Unpack[_Ts]]):
    def __new__(cls, __item1: _T1, *items: Unpack[_Ts1]) -> itemgetter[_T1, Unpack[_Ts1]]: ...
    @overload
    def __call__(self: itemgetter[_T1], obj: SupportsGetItem[_T1, _R]) -> _R: ...
    @overload
    def __call__(self: itemgetter[_T1, _T2], obj: SupportsGetItem[_T1 | _T2, _R]) -> tuple[_R, _R]: ...
    @overload
    def __call__(self: itemgetter[_T1, _T2, _T3], obj: SupportsGetItem[_T1 | _T2 | _T3, _R]) -> tuple[_R, _R, _R]: ...
    @overload
    def __call__(
        self: itemgetter[_T1, _T2, _T3, _T4], obj: SupportsGetItem[_T | _T2 | _T3 | _T4, _R]
    ) -> tuple[_R, _R, _R, _R]: ...
    @overload
    def __call__(
        self: itemgetter[_T1, _T2, _T3, _T4, _T5], obj: SupportsGetItem[_T1 | _T2 | _T3 | _T4 | _T5, _R]
    ) -> tuple[_R, _R, _R, _R, _R]: ...
    @overload
    def __call__(self, obj: SupportsGetItem[Any, Any]) -> Any: ...

This will crash pytype right now, but I'd actually be curious to see the mypy_primer output, if you fancy trying it!

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
@hamdanal

Copy link
Copy Markdown
Contributor Author

Thanks, this looks good -- I left an inline comment about one more nit, though it doesn't really matter that much.

In general, I'm slightly confused about why we're bothering to make this class generic at all, actually. It doesn't seem like it being generic really does much for us; it's not really possible to express the semantics of this class properly right now, with our current type system. But hey.

I asked myself the same question and I thought it was either used before or is intended to be used in the future so I didn't bother make the class non-generic because I don't have the context for why it was made generic in the first place.

@github-actions

This comment has been minimized.

@hamdanal
hamdanal marked this pull request as draft December 10, 2023 15:58
@github-actions

This comment has been minimized.

This reverts commit 9b2b979.
@hamdanal
hamdanal marked this pull request as ready for review December 10, 2023 16:10
@github-actions

Copy link
Copy Markdown
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@AlexWaygood AlexWaygood left a comment

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.

There's definitely some big TODOs remaining with this class, but this seems like it maintains the status quo for users while simplifying the stub. So I'm happy to merge this now. Thanks!

@AlexWaygood
AlexWaygood merged commit be55326 into python:main Dec 10, 2023
@hamdanal
hamdanal deleted the stdlib-operator-pep646 branch December 10, 2023 16:28
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.

3 participants