Description
(Apologies if this is a typeshed issue.) When calling min
with different types for the iterable and the default, like min(Iterable[T], default=S)
, min
often does not infer the correct type for the result, and gives a confusing error message "Cannot infer type argument 1 of "min"
. I assumed that meant it couldn't infer the type of argument 1, but I think it actually means it can't infer the first (only) type parameter in the definition:
def min(iterable: Iterable[_T], key: Callable[[_T], Any] = ..., default: _T = ...) -> _T: ...
I would expect the result of min(Iterable[T], default=S)
to be:
- The common supertype of S and T (possibly S or T itself), if they share a supertype narrower than Any or object
- Union[S, T] otherwise (Optional[T] in the case S is None)
But maybe that's hard / impossible to express with the type system?
Here's some code that illustrates the problem. Oddly, fixed-length tuples typecheck fine, but variable-length tuples do not. Explicitly specifying the type of the result (which is the same as the type parameter) does not help.
from typing import Tuple, Optional
t1 = (0, 1, 2) # type: Tuple[int, int, int] # The inferred type without any type hint
min(t1, default=None) # typechecks
t2 = (0, 1, 2) # type: Tuple[int, ...]
min(t2, default=None) # error: Cannot infer type argument 1 of "min"
min(t2, default=None) # type: Optional[int] # Does not help
min([0, 1, 2], default=None) # error: Cannot infer type argument 1 of "min"
min(iter((0, 1, 2)), default=None) # error: Cannot infer type argument 1 of "min"
$ python -V ; pip freeze | egrep 'mypy|typing'
Python 3.4.3+
mypy==0.501
typing==3.6.1