Skip to content

Conversation

raabf
Copy link
Contributor

@raabf raabf commented Jul 2, 2021

When the input of __getitem__ is a slice, it returns an instance of the class whatever self currently is:

def __getitem__(self, i):
    if isinstance(i, slice):
        return self.__class__(self.data[i])

https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Lib/collections/__init__.py#L1215-L1217

That would be at least an instance of UserList (and not MutableSequence like currently stated in typeshed) but could be also a subclass. So I changed the return type to an instance of the class of self.

Side note: That problem is already addressed in the python2 typesheds:

def __getitem__(self: _S, s: slice) -> _S: ...

@@ -69,7 +71,7 @@ class UserList(MutableSequence[_T]):
@overload
def __getitem__(self, i: int) -> _T: ...
@overload
def __getitem__(self, i: slice) -> MutableSequence[_T]: ...
def __getitem__(self: _UserListT, i: slice) -> _UserListT[_T]: ...
Copy link
Collaborator

Choose a reason for hiding this comment

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

We actually have a fairly new Self alias for that, which you can import from _typeshed:

from _typeshed import Self

[...]

@overload
    def __getitem__(self: Self, i: slice) -> Self: ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh that would be a very comfortable way. But does that work? Self from _typeshed is defined as Self = TypeVar("Self") (implicitly bound=object) and not TypeVar("_UserListT", bound=UserList) and the UserList.__getitem__ implementation is accessing the attribute self.data, and the upper bound of self namely object does not have this attribute.

Copy link
Collaborator

Choose a reason for hiding this comment

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

A typevar annotating self is implicitly bound to that class. I'm not sure this is documented anywhere, but this is how type checkers work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At least I never read that, and hence did not know about that, … but that behaviour makes life easier. Thanks for explanation! I changed the PR to _typesheld.Self.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 2, 2021

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

@srittau srittau merged commit 1a131a4 into python:master Jul 2, 2021
@raabf raabf deleted the user_list_getitem_return branch July 5, 2021 09:52
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.

2 participants