python / python/mypy

Support for deprecating function arguments

Aperta
#19,817 4 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

feature
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Feature

Currently we can deprecate functions, classes, methods, modules, etc. There should be a clean way to support deprecation of certain function arguments/parameters in a way that the type checker can catch their misuse accordingly.

Pitch

For a function foo this may have many parameters, and for an up coming release we decide one (e.g. bar) is redundant and should be deprecated for some reason (support will be dropped, or another parameter is a better hook for the desired behaviour, etc). Currently I have to write something along the lines of:

def foo(bar: int | None = None): 
  if bar is not None:
    warnings.warn("The use of bar is discouraged for some good reason", DeprecationWarning)
  ...

However, the caller of this function might well be calling foo with either foo(bar=None) or foo(bar=42), when really we would want in both cases the type checker to warn us that bar is deprecated.

I cannot see any support for this in the documentation.

I think there is a way we could do this using overload and dispatch (similar to https://stackoverflow.com/a/73478371/5134817), but I don't think this solution is clean.

Instead I am imagining something along the lines of the behaviour of auto when using enum class, where we can write.

def foo(bar: int | None = deprecated_arg(None, "Don't use bar for some good reason")): ...


x = foo() # No mypy warning.

x = foo(bar=None) # mypy Warning.
x = foo(bar=42) # mypy Warning.

from functools import partial 
sneaky = partial(foo, bar=42)  # mypy Warning. 

Some alternative syntaxes could be:

def foo(bar: Deprecated[int | None, "Don't use bar for some good reason"]): ...  # NB - No default value.

@deprecate_arg(bar="Don't use bar for some good reason")  # Looks similar to functools.partial syntac. 
def foo(bar: int | None): ...  

Of these two alternatives, I don't especially like the decorator approach because it requires writing the argument out twice, so it is easy for this to go out of sync or be a small extra maintenance burden).

Note - I think deprecating certain support for types could be achieved using the type annotation, but imagine this would be a much more complex problem. E.g.

def foo(bar: int | Deprecated[None, "Don't use bar=None for some good reason"] = None): ...

foo(bar=42)  # no mypy warning. 
foo(bar=None)  # mypy Warning. 
foo()  # mypy Warning. 

static or runtime warnings?

In these examples, I mention mypy warnings, meaning static warnings issued by the type checker. I don't wish to conflate these with runtime warnings. Both I think are important, and perhaps there is room for a solution that supports both use cases. But for now I am mostly concerned with achieving the goal with static type checkers.

Guida per i contributori

Apri la guida per i contributori

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

Nell’issue non vengono identificati file o test. Inizia esaminando il supporto esistente di mypy per la deprecazione e l’approccio overload/dispatch menzionato; il lavoro è completato quando si concordano una sintassi supportata e avvisi statici per l’uso di argomenti deprecati, inclusi gli usi espliciti, con valori predefiniti e parziali.

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

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.