python / python/mypy

Mypy can't infer parameter types for nested function calls.

Aperta
#8,666 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

topic-inference
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

I'm trying to run mypy against this code

import itertools
itertools.starmap(
    lambda x, y: True, filter(lambda in_deg: in_deg[1],
                              [(1, 2)]))

I get the following error message:

error: Value of type "Iterable[Any]" is not indexable

It seems like mypy is starting type inference from the outside and inward, so it starts with itertools.starmap. The first callable is considered to take arguments resulting from the unpacking of an iterable: Iterable[Any], hence the second argument is considered Iterable[Iterable[Any]]. Since the second argument to itertools.starmap here is a function call to filter, it's assumed that filter must return Iterable[Iterable[Any]] to match the second argument expected by itertools.starmap. This coerces the second argument to filter to be seen as Iterable[Iterable[Any]], which in turn coerces the first argument to filter to be seen as a callable taking Iteable[Any]. This overlooks the explicitly obvious fact here that the second argument to filter is actually List[Tuple[int, int]](or at worst Iterable[Tuple[int, int]]) which will cause the first filter argument to be a callable that takes Tuple[int, int], effectively suppressing the spurious error.

One way to overcome this misinterpretation of the argument types is to explicitly cast the result of filter to be Iterable[Tuple[int, int]], which will rightfully suppress the error.

import itertools
import typing
itertools.starmap(
    lambda x, y: True, typing.cast(typing.Iterable[typing.Tuple[int, int]],
                                   filter(lambda in_deg: in_deg[1], [(1, 2)])))

mypy version: 0.761
python version: 3.7.6

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo l'errore segnalato con l'esempio annidato di itertools.starmap e filter usando mypy 0.761. Traccia come vengono inferiti i tipi degli argomenti attraverso le due chiamate e confronta il risultato con la versione con cast esplicito. Il lavoro è completato quando l'esempio originale non segnala più lo spurio errore di indicizzazione di Iterable[Any] senza richiedere un cast.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.