Kann jemand helfen, Pythons Mypy-Problem mit dem inkompatiblen Rückgabewerttyp aufgrund von Kovarianz bei der Rückgabe ePython

Python-Programme
Anonymous
 Kann jemand helfen, Pythons Mypy-Problem mit dem inkompatiblen Rückgabewerttyp aufgrund von Kovarianz bei der Rückgabe e

Post by Anonymous »

Es tut mir leid, wenn es bereits eine einfache Antwort gibt, für die ich zu klug bin, um sie zu erkennen. Ich arbeite mit Python 3.13+ und Mypy 1.91.1. Ich habe die Dokumente von mypy gelesen, mehrere ähnliche Fragen/Antworten hier gelesen und Stunden mit KI verbracht.
Ich versuche, einen JSON-Decoder in Python zu schreiben, der funktionale Programmierung verwendet, die ein generisches Ergebnis zurückgibt, anstatt Fehler auszulösen. Ich glaube, das Problem liegt daran, dass mypy denkt, dass sich die zugrunde liegende Datenstruktur irgendwann in der Zukunft ändern kann, und die Verwendung von „Kovariante“ behebt das Problem, aber Mypy beschwert sich darüber, dass Kovariante Parameter sind.
Kann sich jemand den folgenden Code und den Mypy-Fehler ansehen und so einfach wie möglich erklären, warum er auftritt, und wie ich den Code ändern könnte, um die Fehler zu beheben und gleichzeitig unveränderliche Datenklassen beizubehalten?

Code: Select all

from dataclasses import dataclass
from typing import Literal

@dataclass(frozen=True)
class Ok[T]:
value: T

@dataclass(frozen=True)
class Err[E]:
value: E

type Result[T, E] = Ok[T] | Err[E]

@dataclass(frozen=True)
class Dog:
nm: str
kind: Literal['Dog'] = 'Dog'

@dataclass(frozen=True)
class Cat:
nm: str
kind: Literal['Cat'] = 'Cat'

type Animal = Dog | Cat

def decodeDog(slop: dict) -> Result[Dog, str]:
try:
return Ok(Dog(slop["nm"]))
except Exception as e:
return Err(f"Decode Error: {e}")

def decodeCat(slop: dict) -> Result[Cat, str]:
try:
return Ok(Cat(slop["nm"]))
except Exception as e:
return Err(f"Decode Error: {e}")

def decodeAnimal(slop: dict) -> Result[Animal, str]:
match slop.get("kind"):
case "Dog":
return decodeDog(slop)
case "Cat":
return decodeCat(slop)
case _:
return Err("Unknown Animal")

if __name__ == "__main__":
print(decodeDog({"nm": "Spot"}))
print(decodeDog({"someOtherField": "someOtherStuff"}))
print(decodeCat({"nm": "Garfield"}))
print(decodeCat({"someOtherField": "someOtherStuff"}))
print(decodeAnimal({"nm": "Spot", "kind": "Dog"}))
print(decodeAnimal({"nm": "Garfield", "kind": "Cat"}))
print(decodeAnimal({"nm": "ET", "kind": "Animal"}))
Der Code läuft einwandfrei

Code: Select all

❯ python example.py
Ok(value=Dog(nm='Spot', kind='Dog'))
Err(value="Decode Error: 'nm'")
Ok(value=Cat(nm='Garfield', kind='Cat'))
Err(value="Decode Error: 'nm'")
Ok(value=Dog(nm='Spot', kind='Dog'))
Ok(value=Cat(nm='Garfield', kind='Cat'))
Err(value='Unknown Animal')
aber Mypy ist unglücklich

Code: Select all

example.py:42: error: Incompatible return value type (got "Ok[Dog] | Err[str]", expected "Ok[Dog | Cat] | Err[str]")  [return-value]
example.py:44: error: Incompatible return value type (got "Ok[Cat] | Err[str]", expected "Ok[Dog | Cat] | Err[str]")  [return-value]
Vielen Dank!

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post