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

Offen
#2,224 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Anfängerfreundlichkeit
35/100
Issue-Typ
Dokumentation
Klarheit
Größtenteils klar
Aktivitätsstatus
Ruhig
Tech-Stack
python

Rechercherichtung

Beginne mit den im Issue verlinkten Regeln zur Zuweisbarkeit von Callables und reproduziere das Beispiel mit mypy, pyright, ty und pyrefly. Das Issue nennt keine Repository-Dateien oder keinen Conformance-Testpfad; der Abschluss hängt davon ab, zu entscheiden, ob die Zuordnung konstanter Parameter in der Spezifikation geklärt oder dieser Fall zu den Conformance-Tests hinzugefügt werden soll.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

topic: typing spec

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.

Vorherrschende Sprache
Python
Sterne
1.8k
Forks
302
Ø Merge
23 Std.
Gemergte PRs (30 T.)
8

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus python/typing

Alle Issues in python/typing

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.