Browse Source

♻️ Tweak _compat to account for lists of models

pull/14168/head
Sebastián Ramírez 10 months ago
parent
commit
0d4d7d21ad
  1. 1
      fastapi/_compat/__init__.py
  2. 5
      fastapi/_compat/main.py
  3. 9
      fastapi/utils.py

1
fastapi/_compat/__init__.py

@ -33,6 +33,7 @@ from .main import (
from .model_field import ModelField as ModelField
from .shared import PYDANTIC_V2 as PYDANTIC_V2
from .shared import PYDANTIC_VERSION_MINOR_TUPLE as PYDANTIC_VERSION_MINOR_TUPLE
from .shared import annotation_is_pydantic_v1 as annotation_is_pydantic_v1
from .shared import field_annotation_is_scalar as field_annotation_is_scalar
from .shared import (
is_uploadfile_or_nonable_uploadfile_annotation as is_uploadfile_or_nonable_uploadfile_annotation,

5
fastapi/_compat/main.py

@ -205,8 +205,9 @@ def _model_rebuild(model: Type[BaseModel]) -> None:
def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
if fields and isinstance(fields[0], v1.ModelField):
models = v1.get_flat_models_from_fields(fields, known_models=set())
v1_models = [field for field in fields if isinstance(field, v1.ModelField)]
if v1_models:
models = v1.get_flat_models_from_fields(v1_models, known_models=set())
return v1.get_model_name_map(models) # type: ignore[no-any-return]
return {}

9
fastapi/utils.py

@ -23,11 +23,12 @@ from fastapi._compat import (
Undefined,
UndefinedType,
Validator,
annotation_is_pydantic_v1,
lenient_issubclass,
v1,
)
from fastapi.datastructures import DefaultPlaceholder, DefaultType
from pydantic import BaseModel, create_model
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from typing_extensions import Literal
@ -86,7 +87,7 @@ def create_model_field(
) -> ModelField:
class_validators = class_validators or {}
if lenient_issubclass(type_, v1.BaseModel) or version == "1":
if annotation_is_pydantic_v1(type_) or version == "1":
model_config = v1.BaseConfig
field_info = field_info or v1.FieldInfo()
kwargs = {
@ -124,6 +125,7 @@ def create_cloned_field(
) -> ModelField:
if PYDANTIC_V2:
from ._compat import v2
if isinstance(field, v2.ModelField): # type: ignore[name-defined]
return field
# cloned_types caches already cloned types to support recursive models and improve
@ -143,7 +145,8 @@ def create_cloned_field(
cloned_types[original_type] = use_type
for f in original_type.__fields__.values():
use_type.__fields__[f.name] = create_cloned_field(
f, cloned_types=cloned_types,
f,
cloned_types=cloned_types,
)
new_field = create_model_field(name=field.name, type_=use_type, version="1")
new_field.has_alias = field.has_alias # type: ignore[attr-defined]

Loading…
Cancel
Save