Description
I'm using mypy 0.701 on Python 3.7.2, no flags.
When run on the following code:
from typing import Iterable, Optional
def longest(values: Iterable[str]) -> Optional[str]:
return max(values, key=len, default=None)
print(longest(['badger', 'mushroom', 'snake']))
print(longest([]))
mypy reports:
4: error: Argument "key" to "max" has incompatible type "Callable[[Sized], int]"; expected "Callable[[Optional[str]], Any]"
While this looks similar to #6460, the root cause is not the same: mypy 0.701 contains the updated typeshed with a signature that uses a Union
for the return type of max
. Also the test case from that issue passes now. The difference with my test case seems to be in the expected return type.
To make absolutely certain that the built-in signature is not the problem, I created this test case that uses a custom mox
function with the same signature as max
:
from typing import Any, Callable, Iterable, Optional, TypeVar, Union
_T = TypeVar('_T')
_VT = TypeVar('_VT')
def mox(iterable: Iterable[_T],
key: Callable[[_T], Any],
default: _VT
) -> Union[_T, _VT]: ...
def moxest(values: Iterable[str]) -> Optional[str]:
return mox(values, key=len, default=None)
def has_mox(values: Iterable[str]) -> bool:
return bool(mox(values, key=len, default=None))
mypy reports:
12: error: Argument "key" to "mox" has incompatible type "Callable[[Sized], int]"; expected "Callable[[Optional[str]], Any]"
15: error: Argument "key" to "mox" has incompatible type "Callable[[Sized], int]"; expected "Callable[[object], Any]"
So the expected value type seems to be influenced by the expected return type of the expression, instead of being determined solely by the argument types.
I guess there could be situations in which picking a weaker value type is useful, but in this case the weaker type causes a false positive.