Skip to content

new protocol, overloads to list.sort, sorted; prep. to fix #4051, #4155

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

Closed
wants to merge 9 commits into from
22 changes: 17 additions & 5 deletions stdlib/2/__builtin__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ if sys.version_info >= (3, 8):
else:
from typing_extensions import Literal

class _SupportsIndex(Protocol):
def __index__(self) -> int: ...

class _SupportsLessThan(Protocol):
def __lt__(self, other: Any) -> bool: ...

_T = TypeVar('_T')
_T_co = TypeVar('_T_co', covariant=True)
_KT = TypeVar('_KT')
Expand All @@ -37,9 +43,7 @@ _T3 = TypeVar('_T3')
_T4 = TypeVar('_T4')
_T5 = TypeVar('_T5')
_TT = TypeVar('_TT', bound='type')

class _SupportsIndex(Protocol):
def __index__(self) -> int: ...
_LT = TypeVar('_LT', bound=_SupportsLessThan)

class object:
__doc__: Optional[str]
Expand Down Expand Up @@ -943,7 +947,10 @@ class list(MutableSequence[_T], Generic[_T]):
def remove(self, __value: _T) -> None: ...
def reverse(self) -> None: ...
if sys.version_info >= (3,):
def sort(self, *, key: Optional[Callable[[_T], Any]] = ..., reverse: bool = ...) -> None: ...
@overload
def sort(self: List[_SupportsLessThan], *, key: None = ..., reverse: bool = ...) -> None: ...
Copy link
Member

Choose a reason for hiding this comment

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

This must actually be List[_LT] to avoid the invariance issue mentioned in my comment.

@overload
def sort(self, *, key: Callable[[_T], _SupportsLessThan], reverse: bool = ...) -> None: ...
else:
def sort(self, cmp: Callable[[_T, _T], Any] = ..., key: Callable[[_T], Any] = ..., reverse: bool = ...) -> None: ...

Expand Down Expand Up @@ -1539,8 +1546,13 @@ else:
def round(number: SupportsFloat, ndigits: int) -> float: ...
def setattr(__obj: Any, __name: Text, __value: Any) -> None: ...
if sys.version_info >= (3,):
@overload
def sorted(__iterable: Iterable[_LT], *,
key: None = ...,
reverse: bool = ...) -> List[_LT]: ...
@overload
def sorted(__iterable: Iterable[_T], *,
key: Optional[Callable[[_T], Any]] = ...,
key: Callable[[_T], _LT],
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here.

Copy link
Contributor Author

@ramalho ramalho Jun 2, 2020

Choose a reason for hiding this comment

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

I will implement this change as well. Thanks, @srittau !

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @srittau here. A typevar used in a single position doesn't make semantic sense and type checkers could reasonably throw an error for code like this.

Copy link
Member

Choose a reason for hiding this comment

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

But here there is no invariance problem, so the _LT can just be _SupportsLessThan.

reverse: bool = ...) -> List[_T]: ...
else:
def sorted(__iterable: Iterable[_T], *,
Expand Down
22 changes: 17 additions & 5 deletions stdlib/2and3/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ if sys.version_info >= (3, 8):
else:
from typing_extensions import Literal

class _SupportsIndex(Protocol):
def __index__(self) -> int: ...

class _SupportsLessThan(Protocol):
def __lt__(self, other: Any) -> bool: ...

_T = TypeVar('_T')
_T_co = TypeVar('_T_co', covariant=True)
_KT = TypeVar('_KT')
Expand All @@ -37,9 +43,7 @@ _T3 = TypeVar('_T3')
_T4 = TypeVar('_T4')
_T5 = TypeVar('_T5')
_TT = TypeVar('_TT', bound='type')

class _SupportsIndex(Protocol):
def __index__(self) -> int: ...
_LT = TypeVar('_LT', bound=_SupportsLessThan)

class object:
__doc__: Optional[str]
Expand Down Expand Up @@ -943,7 +947,10 @@ class list(MutableSequence[_T], Generic[_T]):
def remove(self, __value: _T) -> None: ...
def reverse(self) -> None: ...
if sys.version_info >= (3,):
def sort(self, *, key: Optional[Callable[[_T], Any]] = ..., reverse: bool = ...) -> None: ...
@overload
def sort(self: List[_SupportsLessThan], *, key: None = ..., reverse: bool = ...) -> None: ...
@overload
def sort(self, *, key: Callable[[_T], _SupportsLessThan], reverse: bool = ...) -> None: ...
else:
def sort(self, cmp: Callable[[_T, _T], Any] = ..., key: Callable[[_T], Any] = ..., reverse: bool = ...) -> None: ...

Expand Down Expand Up @@ -1539,8 +1546,13 @@ else:
def round(number: SupportsFloat, ndigits: int) -> float: ...
def setattr(__obj: Any, __name: Text, __value: Any) -> None: ...
if sys.version_info >= (3,):
@overload
def sorted(__iterable: Iterable[_LT], *,
key: None = ...,
reverse: bool = ...) -> List[_LT]: ...
@overload
def sorted(__iterable: Iterable[_T], *,
key: Optional[Callable[[_T], Any]] = ...,
key: Callable[[_T], _LT],
reverse: bool = ...) -> List[_T]: ...
else:
def sorted(__iterable: Iterable[_T], *,
Expand Down