Reputation: 89
I have some code that looks like this:
di: dict[str, float]
max_val = max(di, key=di.get)
When running mypy
on it, it complains
error: Argument "key" to "max" has incompatible type overloaded function; expected "Callable[[str], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]"
My guess is that this is because the return type of di.get
is Union[float, None]
in general, but in this specific instance, it should always return a float
since the function is only being called on keys from di
. The three workarounds I've discovered are to define a custom lambda function, ignore the di.get
call, or cast
it as follows.
get_lambda = lambda key: di[key]
max_val = max(di, key=get_lambda)
# ---------
max_val = max(
di,
key=di.get, # type: ignore [arg-type]
)
# ---------
from typing import cast, Callable
max_val = max(di, key=cast(Callable[[str], float], di.get))
Is there a more proper/standard way of letting mypy
know that the get
method will not be returning None
?
Upvotes: 4
Views: 1474
Reputation: 2312
The dunder (double underscore) member function __getitem__
of a dict
object is what you want here:
max(di, key=di.__getitem__)
raises no complains from mypy
. The reason your lambda works is because it precisely emulates the intent of __getitem__
, which is to implement evaluation of self[key]
, as explained in the documentation.
Upvotes: 4