python / python/mypy

Rust style force handling of return value

Aperta
#6,936 27 commenti 18 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

I tried to implement something like Rust's Result type. The interesting thing is that it has a linting attribute called #[must_use] which makes the linter enforce that the value is not ignored when used as a return type.

I think this could be very helpful when implementing functions that returns status and you want to ensure that it is not unhandled.

Consider the following toy implementation:

from typing import cast, Generic, Optional, TypeVar, Union
from whereever import MustUse

T = TypeVar("T")
E = TypeVar("E")

# We inherit from MustUse to ensure this type isn't ignore
class Result(Generic[T, E], MustUse):
    def __init__(self, value: Union[T, E], is_ok: bool):
        self._value = value
        self.is_ok = is_ok

    @classmethod
    def ok(cls, value: T) -> "Result[T, E]":
        return cls(value, is_ok=True)

    @classmethod
    def error(cls, value: E) -> "Result[T, E]":
        return cls(value, is_ok=True)

    @property
    def is_error(self) -> bool:
        return not self.is_ok

    def get_value(self) -> Optional[T]:
        if self.is_ok:
            return cast(T, self._value)
        return None

    def get_error(self) -> Optional[E]:
        if not self.is_ok:
            return cast(E, self._value)
        return None

def f(success: bool) -> Result[str, int]:
    if not success:
        return Result[str, int].error(123)
    return Result[str, int].ok("Hello")


# No warning is raised since the value is saved to a variable
a = f(True)

# No warning is raised since we convert the Result into an Optional
f(False).get_value()

# This will raise a warning since we never do anything with the Result like:
#     error: unused return value with attribute MustUse
# or
#     error: return value of function call must be used
f(True)

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

L’issue non indica file mypy, test o punti di ingresso. Inizia esaminando l’architettura del controllo dei tipi e del linting di mypy, quindi definisci come distinguere un valore restituito Result-like da un valore consumato intenzionalmente; il lavoro è completato quando i valori restituiti di stato ignorati vengono diagnosticati senza avvisi per i risultati assegnati o consumati esplicitamente.

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

Valutazione

Stack tecnologico
python, rust
Ambito
tooling
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Tranquilla
Chiarezza
Da chiarire
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.