Skip to content

2.12: serialize_as_any issuesΒ #12382

@davidhewitt

Description

@davidhewitt

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:

  1. Check if you can make use of the SerializeAsAny annotation instead, and apply it only on fields if this is necessary.
  2. 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_any usage. If you use it to achieve duck typing serialization of subclasses, we may introduce a new value for serialize_as_any(e.g. a literal 'subclasses', name TBD), on top of the existing True/False. Please share use cases in this issue so that we can decide on the best path to take.
  3. 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 between pydantic and pydantic-core, needs design, challenges as always are config and caching)
  • for the case of SerializeAsAny annotation and serialize_as_any runtime flag, there is type information which we could use to generate a fallback serializer if inference fails

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug V2Bug related to Pydantic V2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions