-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
max() uses SupportsGreaterThanT #6342
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
Conversation
Add SupportsGreaterThan and SupportsGreaterThanT Closes: python#6336
I have no idea what the pre-commit check is trying to tell me. |
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
Looks like it is already enabled and is looking for a config file. Which is not yet merged: #6341 |
Co-authored-by: Jelle Zijlstra <[email protected]>
Diff from mypy_primer, showing the effect of this PR on open source code: pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/arrays/sparse/array.py:1550: error: Cannot call function of unknown type [operator]
|
I don't think the solution can be this simple, unfortunately. Consider the following class definitions: class OnlyKnowsDunderLT:
def __init__(self, n):
self.n = n
def __lt__(self, other):
return self.n < other.n
def __repr__(self):
return f'OnlyKnowsDunderLT(n={self.n})'
class OnlyKnowsDunderGT:
def __init__(self, n):
self.n = n
def __gt__(self, other):
return self.n > other.n
def __repr__(self):
return f'OnlyKnowsDunderGT(n={self.n})' Here's how they behave with >>> max(OnlyKnowsDunderLT(5), OnlyKnowsDunderLT(6))
OnlyKnowsDunderLT(n=6)
>>> max(OnlyKnowsDunderGT(3), OnlyKnowsDunderGT(8))
OnlyKnowsDunderGT(n=8)
>>> max(OnlyKnowsDunderLT(3), OnlyKnowsDunderGT(9))
OnlyKnowsDunderGT(n=9) I believe that this may be because the following works just fine, due to the way the expression >>> OnlyKnowsDunderLT(2) > OnlyKnowsDunderLT(8)
False A solution I was wondering about (which I haven't tested, nor checked against the C code to see whether it would be accurate) was something along these lines: from typing import Protocol, TypeVar, Union, Any
class _SupportsDunderLT(Protocol):
def __lt__(self, other: Any) -> bool: ...
class _SupportsDunderGT(Protocol):
def __gt__(self, other: Any) -> bool: ...
SupportsComparisons = Union[_SupportsDunderGT, _SupportsDunderLT]
SupportsComparisonsT = TypeVar('SupportsComparisonsT', bound=SupportsComparisons) ...and then use |
@AlexWaygood That's because |
@srittau, the following snippet of code fails mypy, despite running fine at runtime, indicating that from typing import Protocol, Any, TypeVar
class SupportsGreaterThan(Protocol):
def __gt__(self, other: Any) -> bool: ...
SupportsGreaterThanT = TypeVar('SupportsGreaterThanT', bound=SupportsGreaterThan)
def mymax(*iterables: SupportsGreaterThanT) -> SupportsGreaterThanT:
return max(iterables) # type: ignore[type-var]
class HasLessThan:
def __init__(self, n: int) -> None:
self.n = n
def __lt__(self, other: HasLessThan) -> bool:
return self.n < other.n
def __repr__(self) -> str:
return f'HasLessThan(n={self.n})'
mymax(HasLessThan(5), HasLessThan(8)) # error: Value of type variable "SupportsGreaterThanT" of "mymax" cannot be "HasLessThan" [type-var] |
Considering that this is ultimately passed to |
Add SupportsGreaterThan and SupportsGreaterThanT
Closes: #6336