Mypy: Type inference in high level function

Created on 9 Dec 2019  路  3Comments  路  Source: python/mypy

For fully valid code got:
error: Argument 1 to "map" has incompatible type overloaded function; expected "Callable[[Iterator[_T], int, None], Iterator[_T]].

In foo.py:

from typing import Generic, Iterable, Iterator, Sequence, TypeVar
_T = TypeVar('_T')

class Windowed(Generic[_T]):
    def __init__(self, it: Iterable[_T], size: int) -> None:
        self.it = it
        self.size = size

    def __iter__(self) -> Iterator[Sequence[_T]]:
        iters = tee(self.it, self.size)
        slices = map(islice, iters, count(0), repeat(None))
        return zip(*slices)

However islice has overload:

def islice(iterable: Iterable[_T], start: Optional[int], stop: Optional[int],
           step: Optional[int] = ...) -> Iterator[_T]: ...

Using mypy 0.750 from PyPI, on python 3.7.5. Running it via mypy foo.py

bug false-positive priority-1-normal

Most helpful comment

Another one:

from typing import Callable,  Iterable, List, Type, TypeVar
_T = TypeVar('_T')
_U = TypeVar('_U')

def map1(fn: Callable[[_T], _U], it: Iterable[_T]) -> Iterable[_U]: ...

items: List[List[int]] = []
map1(tuple, items)

Triggers:
Argument 1 to "map1" has incompatible type "Type[Tuple[Any, ...]]"; expected "Callable[[List[int]], Tuple[_T_co, ...]]"

However, this works, but doesn't check that items in Iterable are convertible to _U:

def map1(fn: Type[_U], it: Iterable) -> Iterable[_U]: ...

Why types are not treated as callables, when they are?
How to define function which accept tuple and treats it correctly, both as Type[Tuple[Any, ...]], and as Callable[[Iterable[_T]], Tuple[_T, ...]]?

All 3 comments

This one looks nasty. I did some minimization work and despite both map and islice being overloaded, it looks like that is surprisingly not the culprit.

The following minimization exhibits the same issue:

from typing import Generic, Iterable, Iterator, TypeVar, Callable
_T = TypeVar('_T')
_S = TypeVar('_S')

def ident(x: _T) -> _T: pass
def map1(__func: Callable[[_T], _S], __iter1: Iterable[_T]) -> Iterator[_S]: ...

class X(Generic[_T]):
#class X:  # If the variable is a function level type var then this works
    def f(self, it: Iterable[_T]) -> None:
        slices = map1(ident, it)

If the type variable is bound at the function instead of the class, then it works.

Another one:

from typing import Callable,  Iterable, List, Type, TypeVar
_T = TypeVar('_T')
_U = TypeVar('_U')

def map1(fn: Callable[[_T], _U], it: Iterable[_T]) -> Iterable[_U]: ...

items: List[List[int]] = []
map1(tuple, items)

Triggers:
Argument 1 to "map1" has incompatible type "Type[Tuple[Any, ...]]"; expected "Callable[[List[int]], Tuple[_T_co, ...]]"

However, this works, but doesn't check that items in Iterable are convertible to _U:

def map1(fn: Type[_U], it: Iterable) -> Iterable[_U]: ...

Why types are not treated as callables, when they are?
How to define function which accept tuple and treats it correctly, both as Type[Tuple[Any, ...]], and as Callable[[Iterable[_T]], Tuple[_T, ...]]?

list_B = list(set([dict_B[i] for i n list_C])) list_of_key_values = list(set(list_A).intersection(list_B)) list_ 1= [dict_A[dict_key] for dict_key in list_of_key_values] list_1= list(map(int, list_1))

where type hints are:

  • list_A: List[str]

-list_C List[int]

  • dict_A & dict_B: Dict[int, str]

error: Argument 1 to "map" has incompatible type "Type[int]"; expected "Callable[[List[int]], int]"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Stiivi picture Stiivi  路  3Comments

mplanchard picture mplanchard  路  3Comments

gregbedwell picture gregbedwell  路  3Comments

jstasiak picture jstasiak  路  3Comments

JukkaL picture JukkaL  路  4Comments