RecursionError in combination with Dataclasses and create_model #4949
Closed
Description
Initial Checks
- I have searched GitHub for a duplicate issue and I'm sure this is something new
- I have searched Google & StackOverflow for a solution and couldn't find anything
- I have read and followed the docs and still think this is a bug
- I am confident that the issue is with pydantic (not my code, or another library in the ecosystem like FastAPI or mypy)
Description
I'm getting a RecursionError
when calling pydantic.create_model
with a __base__
class that contains fields which are both pydantic and vanilla dataclasses.
Most of the recursion related problems I could find were related to recursive data types (such as #1370). There is no (obvious) recursion in the data structures I use.
Traceback (most recent call last):
File "/home/martin/.config/JetBrains/PyCharm2022.3/scratches/scratch_26.py", line 15, in <module>
pydantic.create_model("ArbitraryName", __base__=ResponseSchema)
File "pydantic/main.py", line 1027, in pydantic.main.create_model
File "pydantic/main.py", line 139, in pydantic.main.ModelMetaclass.__new__
File "pydantic/utils.py", line 695, in pydantic.utils.smart_deepcopy
File "/home/martin/.pyenv/versions/3.11.0/lib/python3.11/copy.py", line 146, in deepcopy
y = copier(x, memo)
^^^^^^^^^^^^^^^
[ whole bunch of deepcopy-related lines omitted ]
File "/home/martin/.pyenv/versions/3.11.0/lib/python3.11/copy.py", line 272, in _reconstruct
if hasattr(y, '__setstate__'):
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "pydantic/dataclasses.py", line 255, in pydantic.dataclasses.DataclassProxy.__getattr__
'type',
[Previous line repeated 979 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
There is an easy workaround: Don't use both decorators.
Unfortunately, I need both because the class is defined in another module and I need to wrap it with pydantic for I/O validation.
Originally, I ran into this problem using FastAPI, but managed to reproduce it using pydantic alone. So I hope this is the correct place to ask.
Example Code
import dataclasses
import pydantic
@pydantic.dataclasses.dataclass
@dataclasses.dataclass
class ValueObj:
name: str
class ResponseSchema(pydantic.BaseModel):
value: ValueObj
pydantic.create_model("ArbitraryName", __base__=ResponseSchema)
Python, Pydantic & OS Version
pydantic version: 1.10.4
pydantic compiled: True
install path: /home/martin/.cache/pypoetry/virtualenvs/private/lib/python3.11/site-packages/pydantic
python version: 3.11.0 (main, Nov 7 2022, 07:51:46) [GCC 12.2.0]
platform: Linux-6.1.4-arch1-1-x86_64-with-glibc2.36
optional deps. installed: ['typing-extensions']
Also reproducible with slightly older versions:
pydantic version: 1.10.2
pydantic compiled: True
install path: /home/martin/.cache/pypoetry/virtualenvs/private/lib/python3.9/site-packages/pydantic
python version: 3.9.7 (default, Nov 7 2022, 07:48:33) [GCC 12.2.0]
platform: Linux-6.1.4-arch1-1-x86_64-with-glibc2.36
optional deps. installed: ['typing-extensions']
Affected Components
- Compatibility between releases
- Data validation/parsing
- Data serialization -
.model_dump()
and.model_dump_json()
- JSON Schema
- Dataclasses
- Model Config
- Field Types - adding or changing a particular data type
- Function validation decorator
- Generic Models
- Other Model behaviour -
model_construct()
, pickling, private attributes, ORM mode - Plugins and integration with other tools - mypy, FastAPI, python-devtools, Hypothesis, VS Code, PyCharm, etc.