Incorrect type inferencing when parameterizing with Self-like type variable involving `__ge__`
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 20.6k
- Forks
- 3.3k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
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.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Empieza ejecutando el reproductor proporcionado con la versión actual de mypy y siguiendo la inferencia para foo, especialmente el parámetro SupportsComparison similar a Self y los métodos ge. Localiza las pruebas relevantes de inferencia de tipos o añade una prueba de regresión para el ejemplo; se considera terminado cuando reveal_type indique tuple[float, float] en lugar de tuple[Fraction, float].
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- devtools
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 28/100