Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fields with BaseModel type that contain an instance of a model that inherits from BaseModel do not get serialized correctly #9378

Closed
1 task done
dmach opened this issue May 2, 2024 · 3 comments
Assignees
Labels

Comments

@dmach
Copy link

dmach commented May 2, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

When I define a field with BaseModel type and assign an instance of a model that inherits from BaseModel, the value gets serialized as {}.

Actual result from the reproducer:

{'parent': {'data': 'DEFAULT'}, 'parent_base_model': {}}

Expected result:

{'parent': {'data': 'DEFAULT'}, 'parent_base_model': {'data': 'DEFAULT'}}

or a validation error while instantiating Child or setting parent_base_model field. I tried setting various model_config options and they did not have any impact (incl. validate_assignment=True and c.parent_base_model=p)

Example Code

from pydantic import *


class Parent(BaseModel):
    data: str = Field(default="DEFAULT")


class Child(BaseModel):
    parent: Parent | None = Field(default=None)
    parent_base_model: BaseModel | None = Field(default=None)


p = Parent()
c = Child(parent=p, parent_base_model=p)
print(c.dict())

Python, Pydantic & OS Version

pydantic version: 2.6.4
        pydantic-core version: 2.16.3
          pydantic-core build: profile=release pgo=false
                 install path: /usr/lib/python3.11/site-packages/pydantic
               python version: 3.11.9 (main, Apr 08 2024, 06:18:15) [GCC]
                     platform: Linux-6.8.7-1-default-x86_64-with-glibc2.39
             related packages: email-validator-2.0.0.post2 mypy-1.9.0 typing_extensions-4.11.0
                       commit: unknown
@dmach dmach added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels May 2, 2024
@RajatRajdeep
Copy link

RajatRajdeep commented May 2, 2024

The parent_base_model attribute is of type BaseModel, and since BaseModel does not include a data attribute, the data attribute was ignored in the validation. You can refer to the documentation on extra fields for more information: link.

@dmach
Copy link
Author

dmach commented May 6, 2024

If this use case is related to the extra fields behavior, then it's not obvious for me.

Did you mean that if I call Child(parent_base_model=p) with an instance of a subclass, only the fields of the predecessor are used during serialization and fields from the subclass are implicitly "extra" fields from this point of view?

Also, setting extra="forbid" and strict=True makes no difference.

from pydantic import *


class Parent(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
        strict=True,
    )

    data: str = Field(default="DEFAULT")


class Child(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
        strict=True,
    )

    parent: Parent | None = Field(default=None)
    parent_base_model: BaseModel | None = Field(default=None)


p = Parent()
c = Child(parent=p, parent_base_model=p)
print(c.dict())

@sydney-runkle
Copy link
Member

Hi @dmach,

You'll want to use the SerializeAsAny annotation if you want all of the data to be dumped for that second field. For example:

from pydantic import BaseModel, Field, SerializeAsAny


class Parent(BaseModel):
    data: str = Field(default="DEFAULT")


class Child(BaseModel):
    parent: Parent | None = Field(default=None)
    parent_base_model: SerializeAsAny[BaseModel] | None = Field(default=None)


p = Parent()
c = Child(parent=p, parent_base_model=p)
print(c.model_dump())
#> {'parent': {'data': 'DEFAULT'}, 'parent_base_model': {'data': 'DEFAULT'}}

Ping me if you have any questions. You can learn more about that annotation here!

@sydney-runkle sydney-runkle closed this as not planned Won't fix, can't repro, duplicate, stale May 14, 2024
@sydney-runkle sydney-runkle added question and removed bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels May 14, 2024
@sydney-runkle sydney-runkle self-assigned this May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants