Skip to content

Instantly share code, notes, and snippets.

@thejaminator
Last active April 16, 2024 09:51
Show Gist options
  • Save thejaminator/3fcdeeb2f2b6e47451df1bf42bab4233 to your computer and use it in GitHub Desktop.
Save thejaminator/3fcdeeb2f2b6e47451df1bf42bab4233 to your computer and use it in GitHub Desktop.
Pydantic - How to differentiate between types that look the same
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