-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
wrongly reported typing error in min
with key
lambda function and default value when result is Optional
#17221
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
Comments
This is not a stub bug as I expected initially when got bitten by this. The following snippet demonstrates the weird inconsistency: from __future__ import annotations
def foo(x: list[list[int]]) -> list[int] | None:
reveal_type(min(x, key=len, default=None)) # N: Revealed type is "Union[builtins.list[builtins.int], None]"
return min(x, key=len, default=None) # E: Argument "key" to "min" has incompatible type "Callable[[Sized], int]"; expected "Callable[[list[int] | None], SupportsDunderLT[Any] | SupportsDunderGT[Any]]" [arg-type]
foos: list[list[int]]
reveal_type(min(foos, key=len, default=None)) # N: Revealed type is "Union[builtins.list[builtins.int], None]"
min_foo: list[int] | None = min(foos, key=len, default=None) # E: Argument "key" to "min" has incompatible type "Callable[[Sized], int]"; expected "Callable[[list[int] | None], SupportsDunderLT[Any] | SupportsDunderGT[Any]]" [arg-type] Note that
@overload
def min(
arg1: SupportsRichComparisonT, arg2: SupportsRichComparisonT, /, *_args: SupportsRichComparisonT, key: None = None
) -> SupportsRichComparisonT: ...
@overload
def min(arg1: _T, arg2: _T, /, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ...
@overload
def min(iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None) -> SupportsRichComparisonT: ...
@overload
def min(iterable: Iterable[_T], /, *, key: Callable[[_T], SupportsRichComparison]) -> _T: ...
@overload
def min(iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None, default: _T) -> SupportsRichComparisonT | _T: ...
@overload
def min(iterable: Iterable[_T1], /, *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... The relevant overload is the last one. Here's a playground link: https://mypy-play.net/?mypy=master&python=3.11&flags=strict&gist=8b209a7e7c9ddf0c03f3f6dfb0153316 |
Got bitten by this too; the weird thing is that assigning the expression to a (non annotated) name and returning the name works but returning the expression directly errors with from pathlib import Path
from typing import Callable, Any, Iterable
def min_path_good(paths: Iterable[Path], key: Callable[[Path], Any]) -> Path | None:
path = min(paths, key=key, default=None)
return path
def min_path_bad(paths: Iterable[Path], key: Callable[[Path], Any]) -> Path | None:
return min(paths, key=key, default=None) |
Bug Report
When using
key
function inmin
builtin function, default None value and returning it from a function which has anOptional
type, mypy reports a problem where I believe there is none.To Reproduce
Expected Behavior
No errors reported.
Actual Behavior
The error goes away if I remove the
default=None
or when themin
is not in a function withX | None
return type:Here, mypy complains only about
get_min_1
:Your Environment
mypy.ini
(and other config files): (no config)The text was updated successfully, but these errors were encountered: