Incorrect type inferencing when parameterizing with Self-like type variable involving `__ge__`
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 20.6k
- Fork
- 3.3k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
Found a very strange bug involving self-like type variables while using __ge__ and similar methods. The following example defines:
- a parameterized protocol
SupportsComparisonwhich takesSelfas its first parameter and the type being compared to with its other parameter, - a protocol
SupportsRaddwhich allows type-hintingtype(t + supports_radd) == type(t), - a function
fooshould then acceptfoo(x, y, z)wherexsupports comparison withyandzsupports radd withxand returns(x, y).
In the example, foo(float, float, Fraction) -> tuple[float, float] is the expected result, since:
floatsupports comparison withfloatandselfshould befloat, meaningx: SupportsComparison[float, float],Fractionsupports radd withfloat, meaningz: SupportsRadd[float].
However, the result given by reveal_type(...) gives tuple[Fraction, float]. How is this the case?
from typing import Any, Protocol, TypeVar
T = TypeVar("T")
T_con = TypeVar("T_con", contravariant=True)
Self = TypeVar("Self", bound="SupportsComparison[Any, Any]", covariant=True)
class SupportsComparison(Protocol[Self, T_con]):
def __ge__(self: Self, other: T_con) -> bool: ...
def __gt__(self: Self, other: T_con) -> bool: ...
def __le__(self: Self, other: T_con) -> bool: ...
def __lt__(self: Self, other: T_con) -> bool: ...
class SupportsRadd(Protocol[T]):
def __radd__(self, other: T) -> T: ...
X = TypeVar("X", bound=SupportsComparison[Any, Any])
Y = TypeVar("Y")
Z = TypeVar("Z", bound=SupportsRadd[Any])
def foo(
x: SupportsComparison[X, Y],
y: Y,
z: SupportsRadd[X],
) -> tuple[X, Y]:
return (x, y)
from fractions import Fraction
reveal_type(foo(float(), float(), Fraction())) # Revealed type is "Tuple[fractions.Fraction*, builtins.float*]"
- Mypy version:
0.942. - Python version used:
3.10.0.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo il reproducer fornito con la versione corrente di mypy e tracciando l’inferenza per foo, in particolare il parametro SupportsComparison simile a Self e i metodi ge. Individua i test pertinenti sull’inferenza dei tipi oppure aggiungi un test di regressione per l’esempio; il lavoro è completato quando reveal_type segnala tuple[float, float] invece di tuple[Fraction, float].
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
- 28/100