Browse Source

reenables allow_arbitrary_types on the model config when only 1 argument is used on the api endpoint

pull/13694/head
rmawatson 2 months ago
parent
commit
e0212bdc46
  1. 6
      fastapi/dependencies/utils.py
  2. 45
      tests/test_compat.py

6
fastapi/dependencies/utils.py

@ -895,7 +895,11 @@ async def request_body_to_args(
fields_to_extract: List[ModelField] = body_fields
if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel):
if (
single_not_embedded_field
and lenient_issubclass(first_field.type_, BaseModel)
and isinstance(received_body, FormData)
):
fields_to_extract = get_cached_model_fields(first_field.type_)
if isinstance(received_body, FormData):

45
tests/test_compat.py

@ -80,6 +80,51 @@ def test_complex():
assert response2.json() == [1, 2]
@needs_pydanticv2
def test_propagates_pydantic2_model_config():
app = FastAPI()
class Missing:
def __bool__(self):
return False
class EmbeddedModel(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
value: Union[str, Missing] = Missing()
class Model(BaseModel):
model_config = ConfigDict(
arbitrary_types_allowed=True,
)
value: Union[str, Missing] = Missing()
embedded_model: EmbeddedModel = EmbeddedModel()
@app.post("/")
def foo(req: Model) -> Dict[str, Union[str, None]]:
return {
"value": req.value or None,
"embedded_value": req.embedded_model.value or None,
}
client = TestClient(app)
response = client.post("/", json={})
assert response.status_code == 200, response.text
assert response.json() == {
"value": None,
"embedded_value": None,
}
response2 = client.post(
"/", json={"value": "foo", "embedded_model": {"value": "bar"}}
)
assert response2.status_code == 200, response2.text
assert response2.json() == {
"value": "foo",
"embedded_value": "bar",
}
def test_is_bytes_sequence_annotation_union():
# For coverage
# TODO: in theory this would allow declaring types that could be lists of bytes

Loading…
Cancel
Save