mirror of https://github.com/tiangolo/fastapi.git
⚡ Update `create_cloned_field` to use a global cache and improve startup performance (#4645)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com> Co-authored-by: Huon Wilson <wilson.huon@gmail.com>
This commit is contained in:
parent
d057294de1
commit
27618aa2e8
|
|
@ -2,7 +2,18 @@ import re
|
||||||
import warnings
|
import warnings
|
||||||
from dataclasses import is_dataclass
|
from dataclasses import is_dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import TYPE_CHECKING, Any, Dict, Optional, Set, Type, Union, cast
|
from typing import (
|
||||||
|
TYPE_CHECKING,
|
||||||
|
Any,
|
||||||
|
Dict,
|
||||||
|
MutableMapping,
|
||||||
|
Optional,
|
||||||
|
Set,
|
||||||
|
Type,
|
||||||
|
Union,
|
||||||
|
cast,
|
||||||
|
)
|
||||||
|
from weakref import WeakKeyDictionary
|
||||||
|
|
||||||
import fastapi
|
import fastapi
|
||||||
from fastapi.datastructures import DefaultPlaceholder, DefaultType
|
from fastapi.datastructures import DefaultPlaceholder, DefaultType
|
||||||
|
|
@ -16,6 +27,11 @@ from pydantic.utils import lenient_issubclass
|
||||||
if TYPE_CHECKING: # pragma: nocover
|
if TYPE_CHECKING: # pragma: nocover
|
||||||
from .routing import APIRoute
|
from .routing import APIRoute
|
||||||
|
|
||||||
|
# Cache for `create_cloned_field`
|
||||||
|
_CLONED_TYPES_CACHE: MutableMapping[
|
||||||
|
Type[BaseModel], Type[BaseModel]
|
||||||
|
] = WeakKeyDictionary()
|
||||||
|
|
||||||
|
|
||||||
def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
|
def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
|
||||||
if status_code is None:
|
if status_code is None:
|
||||||
|
|
@ -98,11 +114,13 @@ def create_response_field(
|
||||||
def create_cloned_field(
|
def create_cloned_field(
|
||||||
field: ModelField,
|
field: ModelField,
|
||||||
*,
|
*,
|
||||||
cloned_types: Optional[Dict[Type[BaseModel], Type[BaseModel]]] = None,
|
cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None,
|
||||||
) -> ModelField:
|
) -> ModelField:
|
||||||
# _cloned_types has already cloned types, to support recursive models
|
# cloned_types caches already cloned types to support recursive models and improve
|
||||||
|
# performance by avoiding unecessary cloning
|
||||||
if cloned_types is None:
|
if cloned_types is None:
|
||||||
cloned_types = {}
|
cloned_types = _CLONED_TYPES_CACHE
|
||||||
|
|
||||||
original_type = field.type_
|
original_type = field.type_
|
||||||
if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"):
|
if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"):
|
||||||
original_type = original_type.__pydantic_model__
|
original_type = original_type.__pydantic_model__
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue