python / python/mypy

Generic type inferred wrong; curious difference betweer `aiter(f(x))` and `c = f(x); aiter(c)`

Aperta
#16,376 13 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

Bug Report

Consider this code (playground):

from typing import TypeVar, Generic, Callable, Coroutine, Any, AsyncIterator

_T = TypeVar("_T")

class StartedToken:
    pass

class ProducerContext(Generic[_T]):
    pass

async def coro_to_aiter(
    coroutine: Callable[[ProducerContext[_T]], Coroutine[Any, Any, None]]
) -> AsyncIterator[_T | StartedToken]:
    yield StartedToken()

async def coro(ctx: ProducerContext[int]) -> None:
    pass

# Split into two lines, no error:
c = coro_to_aiter(coro)  # no error
it = aiter(c)  # no error

# The same on one line -> mypy error:
it2 = aiter(coro_to_aiter(coro))  # error: Argument 1 to "coro_to_aiter" has incompatible type ...

Expected Behavior

I would expect mypy to not error on the it2 definition line. Moreover, regardless of whether mypy can handle these definitions, I would expect to see the same behavior (error or absence of error) in the "Split into two lines" case and the "on one line" case.

Actual Behavior

I get this error on the it2 line, and no errors on other lines:

main.py:24: error: Argument 1 to "coro_to_aiter" has incompatible type "Callable[[ProducerContext[int]], Coroutine[Any, Any, None]]"; expected "Callable[[ProducerContext[int | StartedToken]], Coroutine[Any, Any, None]]" [arg-type]

Your Environment

  • Mypy version used: 1.6.1 (playground), current master
  • Python version used: 3.11, 3.12

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 con il reproducer main.py dell’issue, usando le versioni di Python e mypy indicate, e confronta i casi aiter(coro_to_aiter(coro)) separato e annidato. Traccia il modo in cui l’inferenza dei tipi generici gestisce ogni chiamata e aggiungi o aggiorna un test di regressione mirato per la discrepanza. Il lavoro è completato quando entrambe le forme ricevono diagnostiche coerenti e previste.

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
42/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.