Skip to content

v2.29.0 introduced a bug with serialization that uses a wrapped serializer #1651

Closed
@ornariece

Description

@ornariece
import pydantic


class MyModel(pydantic.RootModel):
    root: str

    @pydantic.model_serializer(mode="wrap")
    def my_wrapper_serializer(self, serializer: pydantic.SerializerFunctionWrapHandler):
        return "my_prefix:" + serializer(self)


class MyParentModel(pydantic.BaseModel):
    nested: MyModel

    @pydantic.field_serializer('nested', mode="wrap")
    def wrapped_field_serializer(
        self, field_value, serializer: pydantic.SerializerFunctionWrapHandler
    ):
        return serializer(field_value)


if __name__ == "__main__":
    my_model = MyParentModel.model_validate({'nested': "validated_value"})

    print(my_model.model_dump())
    #>expected: {'nested': 'my_prefix:validated_value'}
    #>actual:   {'nested': 'my_prefix:my_prefix:validated_value'}

i've narrowed down the issue to the "bump to pydantic-core 2.29.0" commit in pydantic.

taking a quick look at what changed in pydantic-core in that version, it seems the bug was introduced by this commit about memory optimization? it looks like the to_python method is naively delegating to the schema serializer without accounting for the wrapping mode. i know little about rust, and haven't really investigated so i could be far off here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions