fastapi: RecursionError from response model in 0.47.1
Describe the bug
FastAPI 0.47.1 will not be able to start due to a RecursionError when there is a circular reference among models. The issue seems to originate from https://github.com/tiangolo/fastapi/pull/889. This works fine in 0.46.0.
Environment
- OS: Windows
- FastAPI Version: 0.47.1
- Python version: 3.7.0
To Reproduce
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, Field
class Group(BaseModel):
representative: Optional['Person'] = Field(None)
class Person(BaseModel):
group: Optional[Group] = Field(None)
Group.update_forward_refs()
app = FastAPI()
@app.get('/group/{group_id}', response_model=Group)
def get_group(group_id):
return []
Expected behavior
No exception
Actual output
Traceback (most recent call last):
File "test.py", line 21, in <module>
@app.get('/group/{group_id}', response_model=Group)
File "D:\virtualenvs\test\lib\site-packages\fastapi\routing.py", line 494, in decorator
callbacks=callbacks,
File "D:\virtualenvs\test\lib\site-packages\fastapi\routing.py", line 438, in add_api_route
callbacks=callbacks,
File "D:\virtualenvs\test\lib\site-packages\fastapi\routing.py", line 275, in __init__
] = create_cloned_field(self.response_field)
File "D:\virtualenvs\test\lib\site-packages\fastapi\utils.py", line 100, in create_cloned_field
use_type.__fields__[f.name] = create_cloned_field(f)
File "D:\virtualenvs\test\lib\site-packages\fastapi\utils.py", line 100, in create_cloned_field
use_type.__fields__[f.name] = create_cloned_field(f)
File "D:\virtualenvs\test\lib\site-packages\fastapi\utils.py", line 100, in create_cloned_field
use_type.__fields__[f.name] = create_cloned_field(f)
[Previous line repeated 981 more times]
File "D:\virtualenvs\test\lib\site-packages\fastapi\utils.py", line 97, in create_cloned_field
original_type.__name__, __config__=original_type.__config__
File "D:\virtualenvs\test\lib\site-packages\pydantic\main.py", line 773, in create_model
return type(model_name, (__base__,), namespace)
File "D:\virtualenvs\test\lib\site-packages\pydantic\main.py", line 152, in __new__
if issubclass(base, BaseModel) and base != BaseModel:
File "D:\virtualenvs\test\lib\abc.py", line 143, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
RecursionError: maximum recursion depth exceeded in comparison
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 6
- Comments: 17 (10 by maintainers)
Commits related to this issue
- FIX: #894 — committed to l3str4nge/fastapi by deleted user 4 years ago
- FIX: #894 Include recursion check for create_cloned_field. Added test for recursive model. — committed to voegtlel/fastapi by deleted user 4 years ago
- FIX: #894 — committed to jacobsvante/fastapi by deleted user 4 years ago
- :bug: Check already cloned fields in create_cloned_field to support recursive models (#1164) * FIX: #894 Include recursion check for create_cloned_field. Added test for recursive model. * :recyc... — committed to hyahiaoui/fastapi by voegtlel 4 years ago
Thanks for the discussion here everyone!
This was fixed by @voegtlel in https://github.com/tiangolo/fastapi/pull/1164 🚀 🎉
It will be available in the next release (today in a couple of hours).
I’ll re-open this issue to give @ysmu a chance to confirm it’s fixed and close it.
Ah thanks for fixing this, our front-end team really appreciates it 😉
Fix works for me. Thank you!
Hi there, I’ve suggested another MR to fix this issue. The one of @mateuszz0000 was missing the recursive field resolution. EDIT: Coverage showed me I was wrong here and used an older version of fastapi for my initial test of the fix 🙈 Works without that part (so removed it from the commit).
Still, I think local cloning (i.e. keeping dicts of what was cloned) should be preferred before setting another hidden attribute?
Sorry just tested it again, and got the same issue on MacOS. Might have been an older version of FastAPI.