Spec/Conformance: subtyping callables with non-constant parameter mapping.
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 1.8k
- Fork
- 302
- Merge medio
- 23h
- PR unite (30g)
- 8
Descrizione
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.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
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 con le regole di assegnabilità dei callable collegate nell’issue e riproduci l’esempio con mypy, pyright, ty e pyrefly. L’issue non indica alcun file del repository né alcun percorso per i test di conformità; il completamento dipende dal decidere se chiarire nella specifica la mappatura dei parametri costanti o aggiungere questo caso ai test di conformità.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- documentation, testing-qa
- Tipo di issue
- Documentazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Tranquilla
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100