python / python/typing

Spec/Conformance: subtyping callables with non-constant parameter mapping.

Abierto
#2,224 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

topic: typing spec
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:

  1. Make(float, float)
  2. Make(float, upper=float)
  3. Make(lower=float, upper=float)

and all these 3 call signatures are supported by make_impl, but the parameter mapping is not constant:

  1. make_impl(float, float) -> {lower:string_or_lower, upper:lower}
  2. make_impl(float, upper=float) -> {lower:string_or_lower, upper:upper}
  3. 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

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. 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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.