python / python/typing

Cannot anotate type of generic functions.

Aperta
#1,938 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

topic: feature
Lingua principale
Python
Stelle
1.8k
Fork
302
Merge medio
23h
PR unite (30g)
8

Descrizione

The current scoping rules for type variables seems to deny type annotations over generic functions.

The issue

define two functions as follows:

def fx_1(f: Callable[[bool], int]) -> int:
    return f(True)

def fx_2[T](f: Callable[[bool], T]) -> T:
    return f(True)

If a function alias is required, these functions can be assigned to variables. However, if type annotations are used, fx_2 cannot be annotated using compliant type checkers (i.e. pyright).

T = TypeVar("T")
fx_1_alias: Callable[[Callable[[bool], int]], int] = fx_1  # OK!
fx_2_alias: Callable[[Callable[[bool], T]], T] = fx_2  # complains that T has no meaning

Justification

  • All variables should be able to be type annotated, even when those variables are functions or the annotation is not required.
  • def is a syntactic sugar equivalent to a variable assignation over a lambda function. As a result, it should be possible to define generic functions without def statements e.g.
fx_2_alternative: Callable[[Callable[[bool], T]], T] =  lambda f: f(True)
  • Generics are the first ladder of what is called a "dependent type". In the case of functions, this corresponds to a Π type where the input itself is the concrete type that will be replaced on the type var of a generic type. Here type-vars scope is over the function type itself rather than some outer entity (class, function, method).
  • By these definitions of Π type, it cannot exist an unbound type variable when function/callable types are involved, since in python, the type argument is implicit and supplied when referring a TypeVar.
    e.g.
T = TypeVar("T")
fx_2_alias: Callable[[Callable[[bool], T]], T] = fx_2
fx_2_alias_2: Callable[[Callable[[bool], T]], T] = fx_2

Even when using the same type var fx_2_alias and fx_2_alias_2 each var is an independent one.
A more clear syntax (like the introduced on def statements on python312) could be

fx_2_alias: Callable[X][[Callable[[bool], X]], X] = fx_2
fx_2_alias_2: Callable[X][[Callable[[bool], X]], X] = fx_2

This marks explicitly that the scope of the var is over the type itself. However, this issue does not aim to propose a new syntax, but rather aims to adjust the scoping rules of type vars.

Motivation

This issue was derived from a pyright issue where generic functions as class instance variables are denied by the checker because of the same scope issues described before.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con gli esempi di funzioni generiche e con l’issue di Pyright collegata, quindi confrontali con le regole attuali sull’ambito delle variabili di tipo. Il lavoro è completo quando la specifica di typing dispone di una risoluzione concordata per l’annotazione delle variabili di funzione generiche e delle variabili di istanza delle classi; l’issue non indica file o test del repository.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
tooling
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
32/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.