![Article preview image Article preview image](/_ipx/h_150&w_300&q_20&f_webp/img/blog/interchange-plus%20.png)
Why Interchange Plus Pricing is the Best Option for Credit Card Processing
Pydantic (and FastAPI which depends heavily on it) seems to be one of the most popular python libraries lately. I did some work with it over the past year, and am now working to extricate it from all of our code. It's really convenient to use at first, but the deeper I got into it, the more problems I ran into. In the end I've come to the conclusion that the problems it solves are better solved with dataclasses and msgspec.
Here are some of the reasons why I think Pydantic is a hot mess.
Pretty much no thought seems to have been given to upgrading existing codebases. Most libraries seem to choose a cut-off version after which they go from supporting only v1 to only v2. Litestar managed to support both versions, but it required this mess.
Obviously this isn't an ongoing problem, unless future breaking changes are handled in the same way.
Good luck! For example, I wanted to deserialize a list of "Record" (another pydantic model) types into a custom list object that has some helper functions. This is what I ended up with (minus the helper functions):
class RecordList(UserList[Record]):
@classmethod
def __get_pydantic_core_schema__(
cls,
source_type: Any, # noqa: ANN401
handler: pydantic.GetCoreSchemaHandler,
) -> cs.CoreSchema:
# Tell pydantic that it can validate this class with the same validator it would use for `Sequence[Record]`
base_schema = handler.generate_schema(Sequence[Record])
return cs.no_info_after_validator_function(
function=cls,
schema=base_schema,
serialization=cs.plain_serializer_function_ser_schema(lambda x: list(x), return_schema=base_schema),
)
The documentation on how to do this is very incomplete and difficult to follow.
Certainly biased, and some of this is out of date with pydantic 2, but a most of it is still valid.
https://threeofwands.com/why-i-use-attrs-instead-of-pydantic/
This is considered not a bug.
import pydantic
class SubModel(pydantic.BaseModel, frozen=True):
v: str = "foo"
class Model(pydantic.BaseModel):
sub: set[SubModel]
m = Model(sub={SubModel()})
m.model_dump() # Fails with TypeError - dict is not hashable
msgspec/dataclasses do not have this problem
import msgspec
@dataclass(frozen=True)
class SubDC:
v: str = "foo"
@dataclass
class DC:
sub: set[SubDC]
obj = DC(sub={SubDC()})
js = msgspec.json.encode(obj)
obj1 = msgspec.json.decode(js, type=DC)
assert obj1 == obj