Skip to content
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

Issue with itemgetter, SupportsGetItem and min #14032

Open
Avasam opened this issue Nov 8, 2022 · 0 comments
Open

Issue with itemgetter, SupportsGetItem and min #14032

Avasam opened this issue Nov 8, 2022 · 0 comments
Labels
bug mypy got something wrong

Comments

@Avasam
Copy link
Sponsor Contributor

Avasam commented Nov 8, 2022

Bug Report
Sorry for the vague title. I'm not sure whether this is a bug or if I'm doing something wrong. This came up in python/typeshed#9117 . Pyright reports no error with the usage of itemgetter here. And both type-checkers reveal the right type returned from min in this example.

To Reproduce

from _typeshed import SupportsDunderGT, SupportsDunderLT
from collections.abc import Callable
from typing import Any, Generic, Protocol, Tuple, TypeVar, Union
from typing_extensions import final

_T = TypeVar("_T")
_T_contra = TypeVar("_T_contra", contravariant=True)
_T_co = TypeVar("_T_co", covariant=True)
_VT_co = TypeVar("_VT_co", covariant=True)
_KT_contra = TypeVar("_KT_contra", contravariant=True)

# Simplified from typeshed
class SupportsGetItem(Protocol[_KT_contra, _VT_co]):
    def __contains__(self, __x: Any) -> bool: ...
    def __getitem__(self, __key: _KT_contra) -> _VT_co: ...

# Simplified from typeshed, with the generic typing change to __call__
@final
class itemgetter(Generic[_T_co]):
    def __new__(cls, item: _T_co) -> itemgetter[_T_co]: ...
    def __call__(self, obj: SupportsGetItem[_T_co, _T]) -> _T: ...

# This is the same as itemgetter.__call__
def standalone_call(obj: SupportsGetItem[int, _T]) -> _T: ...

reveal_type(itemgetter(1).__call__)

test_dict = min({"first": 1, "second": 2}, key=itemgetter(1))
test_items = min({"first": 1, "second": 2}.items(), key=itemgetter(1))  # mypy error
test_dict_standalone = min({"first": 1, "second": 2}, key=standalone_call)
test_items_standalone = min({"first": 1, "second": 2}.items(), key=standalone_call)  # mypy error

reveal_type(test_dict)
reveal_type(test_items)

expected_type_form_min_param_1: Callable[[Tuple[str, int]], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]
revealed_type_itemgetter_call: Callable[[SupportsGetItem[Any, _T]], _T]  # pyright error

revealed_type_itemgetter_call = itemgetter(1)
expected_type_form_min_param_1 = itemgetter(1)  # mypy error

revealed_type_itemgetter_call = standalone_call
expected_type_form_min_param_1 = standalone_call  # mypy error

Expected Behavior

No error? Maybe?

Actual Behavior

(.venv) PS C:\Users\Avasam\Desktop> mypy .\operator_reveal_type.pyi
operator_reveal_type.pyi:26: note: Revealed type is "def [_T] (obj: operator_reveal_type.SupportsGetItem[Any, _T`3]) -> _T`3"
operator_reveal_type.pyi:29: error: Argument "key" to "min" has incompatible type "itemgetter[int]"; expected "Callable[[Tuple[str, int]], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]"  
[arg-type]
operator_reveal_type.pyi:29: note: "itemgetter[int].__call__" has type "Callable[[Arg(SupportsGetItem[Any, _T], 'obj')], _T]"
operator_reveal_type.pyi:31: error: Argument "key" to "min" has incompatible type "Callable[[SupportsGetItem[Any, _T]], _T]"; expected "Callable[[Tuple[str, int]], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]"  [arg-type]
operator_reveal_type.pyi:33: note: Revealed type is "builtins.str"
operator_reveal_type.pyi:34: note: Revealed type is "Tuple[builtins.str, builtins.int]"
operator_reveal_type.pyi:40: error: Incompatible types in assignment (expression has type "itemgetter[int]", variable has type "Callable[[Tuple[str, int]], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]")  [assignment]
operator_reveal_type.pyi:40: note: "itemgetter[int].__call__" has type "Callable[[Arg(SupportsGetItem[Any, _T], 'obj')], _T]"
operator_reveal_type.pyi:43: error: Incompatible types in assignment (expression has type "Callable[[SupportsGetItem[Any, _T]], _T]", variable has type "Callable[[Tuple[str, int]], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]")  [assignment]
Found 4 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 0.982 AND 0.990 (compiled: yes)
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.9.13
@Avasam Avasam added the bug mypy got something wrong label Nov 8, 2022
Avasam added a commit to Avasam/typeshed that referenced this issue Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

1 participant