Can someone tell me why Pydantic is validating a field as a string even though the field type is Json[Any] | str
? And is there a way to have it return a dict instead?
from typing import Any
from pydantic import BaseModel, Json
class FooStr(BaseModel):
json_or_str: Json[Any] | str
class FooInt(BaseModel):
json_or_int: Json[Any] | int
if __name__ == "__main__":
print(type(FooStr(json_or_str='{"a": 1}').json_or_str)) # prints <class 'str'>
print(type(FooInt(json_or_int='{"a": 1}').json_or_int)) # prints <class 'dict'>
Thanks to Karl for the link to the documentation for unions in Pydantic.
I needed union mode left to right. Pydantic defaults to smart mode which will look for the most exact match. In my case a str
was a more exact match than parsing the string into a Json
.
Here's the working code:
from typing import Any
from pydantic import BaseModel, Field, Json
class FooStr(BaseModel):
json_or_str: Json[Any] | str = Field(union_mode="left_to_right")
if __name__ == "__main__":
print(type(FooStr(json_or_str='{"a": 1}').json_or_str)) # prints <class 'dict'>