python / python/mypy

Invalid exported type for lambda arg to overloaded function

Aperta
#12,773 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@JukkaL ci sta già lavorando.

Dal 12/5/2022.

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

Descrizione

This typexport-basic.test test case fails, as an incorrect type is stored for the lambda and the final NameExpr:

[case testExportOverloadArgType]
## LambdaExpr|NameExpr
from typing import List, overload, Callable
@overload
def f(x: int, f: Callable[[int], int]) -> None: ...
@overload
def f(x: str, f: Callable[[str], str]) -> None: ...
def f(x): ...
f(
    1, lambda x: x)
[builtins fixtures/list.pyi]
[out]
NameExpr(8) : Overload(def (x: builtins.int, f: def (builtins.int) -> builtins.int), def (x: builtins.str, f: def (builtins.str) -> builtins.str))
LambdaExpr(9) : def (builtins.int) -> builtins.int
NameExpr(9) : builtins.int

The invalid exported type for the lambda is (str) -> str. The NameExpr has type str, instead of int.

We attempt to infer a type for the lambda once for each overload item. (The type context is taken from the overload item.) The type based on the final overload item is the one that takes precedence, since it gets evaluated last, even if it's not the matching item.

This can cause mypyc to generate incorrect code (see test failures in #12766), since it assumes that the exported types are correct and checks runtime values against them.

I see a few plausible fixes:

  1. Perform another type checking pass using the matching overload item as context. This has the drawback of being potentially quite expensive.
  2. When type checking as part of a search for a matching overload item, store inferred types in a temporary location. Discard the inferred types from each unsuccessful search attempt, and only record the types from the successful attempt.

Option 2 sounds more appealing to me, but it sounds a bit more difficult to implement.

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.

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.