Spec/Conformance: subtyping callables with non-constant parameter mapping.
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 1.8k
- Forks
- 302
- Merge medio
- 23 h
- PR fusionados (30 d)
- 8
Descripción
Consider the example below, which errors with all tested type checkers (mypy/pyright/ty/pyrefly):
from typing import Protocol
class Interval: ...
class Make(Protocol):
def __call__(self, /, lower: float, upper: float) -> Interval: ...
def make_impl(
string_or_lower: str | float | None = None,
/,
lower: float | None = None,
upper: float | None = None,
) -> Interval: ...
def test() -> None:
_f: Make = make_impl # ❌️ type checkers error here.
I believe from a pure type theory POV, this assignment should be legal, because all legal arguments to Make are also legal arguments to make_impl. The spec phrases it in the same spirit:
A callable type B is assignable to a callable type A if the return type of B is assignable to the return type of A and the input signature of B accepts all possible combinations of arguments that the input signature of A accepts. All of the specific assignability rules described below derive from this general rule.
And I couldn't find anything else in https://typing.python.org/en/latest/spec/callables.html#assignability-rules-for-callables that would disallow this assignment.
It seems the type-checkers try to match the KEYWORD_OR_POSITIONAL parameters by name, which is incorrect. Make has 3 legal call signatures:
Make(float, float)Make(float, upper=float)Make(lower=float, upper=float)
and all these 3 call signatures are supported by make_impl, but the parameter mapping is not constant:
make_impl(float, float)->{lower:string_or_lower, upper:lower}make_impl(float, upper=float)->{lower:string_or_lower, upper:upper}make_impl(lower=float, upper=float)->{lower:lower, upper:upper}
So either the spec should demand a constant parameter mapping, or this example should be added to the conformance tests.
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
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
Comienza con las reglas de asignabilidad de callable enlazadas en el issue y reproduce el ejemplo con mypy, pyright, ty y pyrefly. El issue no nombra archivos del repositorio ni una ruta de pruebas de conformidad; la finalización depende de decidir si se debe aclarar en la especificación el mapeo de parámetros constantes o añadir este caso a las pruebas de conformidad.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- documentation, testing-qa
- Tipo de issue
- Documentación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Tranquilo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100