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

BaseModel.model_dump[_xxx](serialize_as_any = True) breaks with models with recursive attribute types (not values) #9670

Open
1 task done
Tracked by #10189
mjog opened this issue Jun 16, 2024 · 4 comments · May be fixed by pydantic/pydantic-core#1359
Assignees
Labels
bug V2 Bug related to Pydantic V2
Milestone

Comments

@mjog
Copy link

mjog commented Jun 16, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Setting the serialize_as_any parameter for the BaseModel.model_dump[_xxx]() methods to True causes an error to be thrown on all models that have a recursive attribute /type/, even if they do not have a recursive /value/.

The SerializeAsAny annotation continues to work fine, but the dump call still fails if the keyword is specified.

This kw param was introduced in 2.7, so it didn't exist in 2.6. I have tested with 2.7.0 - 2.7.4, all have the same problem.

In the example below, all four fail with a ValueError: Circular reference detected (id repeated), e.g.:

Traceback (most recent call last):
  File "/home/mjog/project/test.py", line 24, in <module>
    print(Model1(recursive = None).model_dump(serialize_as_any = True))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mjog/.cache/pypoetry/virtualenvs/project-HUCGNwqs-py3.12/lib/python3.12/site-packages/pydantic/main.py", line 328, in model_dump
    return self.__pydantic_serializer__.to_python(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Circular reference detected (id repeated)

Example Code

from __future__ import annotations

import traceback

import pydantic

class Model1(pydantic.BaseModel):

    recursive: Model1 | None

class Model2(pydantic.BaseModel):

    recursive: pydantic.SerializeAsAny[Model2] | None

# All work fine:
print(Model1(recursive = None).model_dump())
print(Model1(recursive = None).model_dump_json())
print(Model2(recursive = None).model_dump())
print(Model2(recursive = None).model_dump_json())

# All fail:
try:
    print(Model1(recursive = None).model_dump(serialize_as_any = True))
except:
    traceback.print_exc()

try:
    print(Model1(recursive = None).model_dump_json(serialize_as_any = True))
except:
    traceback.print_exc()

try:
    print(Model2(recursive = None).model_dump(serialize_as_any = True))
except:
    traceback.print_exc()

try:
    print(Model2(recursive = None).model_dump_json(serialize_as_any = True))
except:
    traceback.print_exc()

Python, Pydantic & OS Version

pydantic version: 2.7.3
        pydantic-core version: 2.18.4
          pydantic-core build: profile=release pgo=true
                 install path: /home/mjog/.cache/pypoetry/virtualenvs/planet-srv-HUCGNwqs-py3.12/lib/python3.12/site-packages/pydantic
               python version: 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0]
                     platform: Linux-6.8.0-31-generic-x86_64-with-glibc2.39
             related packages: typing_extensions-4.12.2 mypy-1.10.0
                       commit: unknown
@mjog mjog added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Jun 16, 2024
@mjog mjog changed the title BaseModel.model_dump[_xxx](serialize_as_any = True) breaks models with recursive attribute types (not values) BaseModel.model_dump[_xxx](serialize_as_any = True) breaks with models with recursive attribute types (not values) Jun 16, 2024
@mjog
Copy link
Author

mjog commented Jun 16, 2024

NB calling BaseModel.model_rebuild() on the models above does not help.

@sydney-runkle sydney-runkle removed the pending Awaiting a response / confirmation label Jun 19, 2024
@sydney-runkle
Copy link
Member

@mjog,

Thanks for reporting this. Definitely looks like a bug. I'm adding this to our v2.9.0 milestone!

@sydney-runkle sydney-runkle added this to the v2.9.0 milestone Jun 19, 2024
@nix010
Copy link
Contributor

nix010 commented Jun 30, 2024

I can take this if it's ok.

@nix010 nix010 linked a pull request Jul 1, 2024 that will close this issue
4 tasks
@sydney-runkle sydney-runkle self-assigned this Aug 12, 2024
@sydney-runkle sydney-runkle mentioned this issue Aug 20, 2024
19 tasks
@sydney-runkle sydney-runkle modified the milestones: v2.9.0, v2.10 Aug 26, 2024
@ptomecek
Copy link

We ran into this recently while migrating to the serialize_as_any flag. Excited that a fix is in the works, thanks @nix010!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants