python / python/mypy

Rust style force handling of return value

Offen
#6,936 27 Kommentare 18 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

feature priority-2-low
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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)

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Das Issue nennt keine mypy-Dateien, Tests oder Einstiegspunkte. Beginne mit der Durchsicht der Architektur von mypy für Typprüfung und Linting und lege anschließend fest, wie ein Result-like-Rückgabewert von einem absichtlich konsumierten Wert unterschieden wird; abgeschlossen ist die Arbeit, wenn ignorierte Status-Rückgabewerte diagnostiziert werden, ohne eine Warnung für zugewiesene oder explizit konsumierte Ergebnisse auszugeben.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python, rust
Bereich
tooling
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Ruhig
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
30/100

Neue Issues direkt in Ihr Postfach

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