-
-
Couldn't load subscription status.
- Fork 2.3k
Description
Initial Checks
- I confirm that I'm using Pydantic V2
Description
Pydantic has a serialization concept called serialize as any, which can be enabled globally during serialization (using the serialize_as_any parameter) or per field (using the SerializeAsAny annotation). When used, Pydantic treats the type annotation of the field as if it were Any, and tries to infer the value using its actual type (see the documentation for more details).
Up until now, the serialize_as_any flag and SerializeAsAny annotation were behaving quite differently, and they were unified in 2.12 (actually, the serialize_as_any flag behavior was aligned to match the SerializeAsAny annotation).
Unfortunately this also led to regressions where cases that previously serialized in 2.11 no longer serialize in 2.12, because dropping the type information forces pydantic-core to use type inference, and not all types have built-in inference in pydantic-core:
from pydantic import BaseModel, IPvAnyAddress
class BugReproModel(BaseModel):
ip_address: IPvAnyAddress
bug = BugReproModel(ip_address="192.168.1.1")
json_data = bug.model_dump_json(serialize_as_any=True)
# PydanticSerializationError: Unable to serialize unknown type: <class 'ipaddress.IPv4Address'>If you are using the serialize_as_any flag and encountering serialization errors in 2.12:
- Check if you can make use of the
SerializeAsAnyannotation instead, and apply it only on fields if this is necessary. - If you don't control the types you are serializing (e.g. a Pydantic model defined in a third party library), we'd like to know more about your
serialize_as_anyusage. If you use it to achieve duck typing serialization of subclasses, we may introduce a new value forserialize_as_any(e.g. a literal'subclasses', name TBD), on top of the existingTrue/False. Please share use cases in this issue so that we can decide on the best path to take. - If you encountered issues with types such as
IPvAnyAddress, we are looking into improving our type inference logic to support these when serialize as any behavior is applied (see below).
In terms of type inference, we should define more precisely how pydantic-core performs it and expand its functionality to cover as many types as possible.
There are various ways that pydantic-core can currently perform type inference:
- built-in types such as lists, mappings, integers etc
- objects which have a
__pydantic_serializer__attribute (and are not type objects) will use that serializer
I can think of at least two more ways which users would reasonably expect pydantic-core to perform type inference:
- objects which have a
__get_pydantic_core_schema__attribute (and are not type objects) could generate a new serializer from it (this would increase coupling betweenpydanticandpydantic-core, needs design, challenges as always are config and caching) - for the case of
SerializeAsAnyannotation andserialize_as_anyruntime flag, there is type information which we could use to generate a fallback serializer if inference fails