Last active
April 16, 2024 09:51
-
-
Save thejaminator/3fcdeeb2f2b6e47451df1bf42bab4233 to your computer and use it in GitHub Desktop.
Pydantic - How to differentiate between types that look the same
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Literal | |
from pydantic import BaseModel | |
class SomethingThatHasAName(BaseModel): | |
name: str | |
class User(SomethingThatHasAName): | |
... | |
class Product(SomethingThatHasAName): | |
... | |
class Document(BaseModel): | |
relation: User | Product | |
class UserFixed(SomethingThatHasAName): | |
type_name: Literal["User"] = "User" | |
class ProductFixed(SomethingThatHasAName): | |
type_name: Literal["Product"] = "Product" | |
class DocumentFixed(BaseModel): | |
relation: UserFixed | ProductFixed | |
if __name__ == "__main__": | |
doc = Document(relation=Product(name="i am a product")) | |
# Check that the type is Product | |
assert isinstance(doc.relation, Product) | |
# serialize | |
serialized_str = doc.model_dump_json() | |
# Read it back | |
doc2 = Document.model_validate_json(serialized_str) | |
# Check that the type is Product | |
assert isinstance(doc2.relation, Product), "Expected Product, got User" # Fails | |
# Fixed version | |
doc_fixed = DocumentFixed(relation=ProductFixed(name="i am a product")) | |
# Check that the type is Product | |
assert isinstance(doc_fixed.relation, ProductFixed) | |
# serialize | |
serialized_str_2 = doc_fixed.model_dump_json() | |
# Read it back | |
doc_fixed2 = DocumentFixed.model_validate_json(serialized_str_2) | |
# Check that the type is Product | |
assert isinstance(doc_fixed2.relation, ProductFixed), "Expected Product, got User" # Passes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment