Browse Source

️ Format and add types

pull/14168/head
Sebastián Ramírez 10 months ago
parent
commit
9e652f3644
  1. 20
      fastapi/_compat/main.py
  2. 6
      fastapi/_compat/shared.py
  3. 97
      fastapi/_compat/v1.py
  4. 29
      fastapi/_compat/v2.py
  5. 4
      fastapi/encoders.py
  6. 4
      fastapi/utils.py

20
fastapi/_compat/main.py

@ -31,24 +31,26 @@ if PYDANTIC_V2:
with_info_plain_validator_function as with_info_plain_validator_function,
)
else:
from .v1 import BaseConfig as BaseConfig
from .v1 import BaseConfig as BaseConfig # type: ignore[assignment]
from .v1 import FieldInfo as FieldInfo
from .v1 import PydanticSchemaGenerationError as PydanticSchemaGenerationError
from .v1 import ( # type: ignore[assignment]
PydanticSchemaGenerationError as PydanticSchemaGenerationError,
)
from .v1 import RequiredParam as RequiredParam
from .v1 import Undefined as Undefined
from .v1 import UndefinedType as UndefinedType
from .v1 import Url as Url
from .v1 import Url as Url # type: ignore[attr-defined, no-redef]
from .v1 import Validator as Validator
from .v1 import evaluate_forwardref as evaluate_forwardref
from .v1 import get_missing_field_error as get_missing_field_error
from .v1 import (
from .v1 import ( # type: ignore[assignment]
with_info_plain_validator_function as with_info_plain_validator_function,
)
@lru_cache
def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]:
if lenient_issubclass(model, v1.BaseModel): # type: ignore[attr-defined]
if lenient_issubclass(model, v1.BaseModel):
return v1.get_model_fields(model)
else:
from . import v2
@ -67,7 +69,7 @@ def _is_undefined(value: object) -> bool:
def _get_model_config(model: BaseModel) -> Any:
if isinstance(model, v1.BaseModel): # type: ignore[attr-defined]
if isinstance(model, v1.BaseModel):
return v1._get_model_config(model)
elif PYDANTIC_V2:
from . import v2
@ -78,7 +80,7 @@ def _get_model_config(model: BaseModel) -> Any:
def _model_dump(
model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
) -> Any:
if isinstance(model, v1.BaseModel): # type: ignore[attr-defined]
if isinstance(model, v1.BaseModel):
return v1._model_dump(model, mode=mode, **kwargs)
elif PYDANTIC_V2:
from . import v2
@ -195,7 +197,7 @@ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
def _model_rebuild(model: Type[BaseModel]) -> None:
if lenient_issubclass(model, v1.BaseModel): # type: ignore[attr-defined]
if lenient_issubclass(model, v1.BaseModel):
v1._model_rebuild(model)
elif PYDANTIC_V2:
from . import v2
@ -295,7 +297,7 @@ def _is_model_field(value: Any) -> bool:
def _is_model_class(value: Any) -> bool:
if lenient_issubclass(value, v1.BaseModel): # type: ignore[attr-defined]
if lenient_issubclass(value, v1.BaseModel):
return True
elif PYDANTIC_V2:
from . import v2

6
fastapi/_compat/shared.py

@ -98,7 +98,7 @@ def value_is_sequence(value: Any) -> bool:
def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
return (
lenient_issubclass(annotation, (BaseModel, v1.BaseModel, Mapping, UploadFile)) # type: ignore[attr-defined]
lenient_issubclass(annotation, (BaseModel, v1.BaseModel, Mapping, UploadFile))
or _annotation_is_sequence(annotation)
or is_dataclass(annotation)
)
@ -195,12 +195,12 @@ def is_uploadfile_sequence_annotation(annotation: Any) -> bool:
def annotation_is_pydantic_v1(annotation: Any) -> bool:
if lenient_issubclass(annotation, v1.BaseModel): # type: ignore[attr-defined]
if lenient_issubclass(annotation, v1.BaseModel):
return True
origin = get_origin(annotation)
if origin is Union or origin is UnionType:
for arg in get_args(annotation):
if lenient_issubclass(arg, v1.BaseModel): # type: ignore[attr-defined]
if lenient_issubclass(arg, v1.BaseModel):
return True
if field_annotation_is_sequence(annotation):
for sub_annotation in get_args(annotation):

97
fastapi/_compat/v1.py

@ -26,19 +26,13 @@ PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
RequiredParam: Any = Ellipsis
if not PYDANTIC_V2:
from pydantic import AnyUrl as Url # noqa: F401
from pydantic import (
BaseConfig as BaseConfig, # noqa: F401
)
from pydantic import BaseModel, create_model
from pydantic import ValidationError as ValidationError # noqa: F401
from pydantic.class_validators import (
Validator as Validator, # noqa: F401
)
from pydantic.color import Color as Color # noqa: F401
from pydantic.error_wrappers import (
ErrorWrapper as ErrorWrapper, # noqa: F401
)
from pydantic import BaseConfig as BaseConfig
from pydantic import BaseModel as BaseModel
from pydantic import ValidationError as ValidationError
from pydantic import create_model as create_model
from pydantic.class_validators import Validator as Validator
from pydantic.color import Color as Color
from pydantic.error_wrappers import ErrorWrapper as ErrorWrapper
from pydantic.errors import MissingError
from pydantic.fields import ( # type: ignore[attr-defined]
SHAPE_FROZENSET,
@ -52,11 +46,11 @@ if not PYDANTIC_V2:
from pydantic.fields import FieldInfo as FieldInfo
from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined]
from pydantic.fields import Undefined as Undefined # type: ignore[attr-defined]
from pydantic.fields import (
UndefinedType as UndefinedType, # type: ignore[attr-defined] # noqa: F401
from pydantic.fields import ( # type: ignore[attr-defined]
UndefinedType as UndefinedType,
)
from pydantic.networks import AnyUrl as AnyUrl # noqa: F401
from pydantic.networks import NameEmail as NameEmail # noqa: F401
from pydantic.networks import AnyUrl as AnyUrl
from pydantic.networks import NameEmail as NameEmail
from pydantic.schema import TypeModelSet as TypeModelSet
from pydantic.schema import (
field_schema,
@ -64,33 +58,26 @@ if not PYDANTIC_V2:
model_process_schema,
)
from pydantic.schema import (
get_annotation_from_field_info as get_annotation_from_field_info, # noqa: F401
get_annotation_from_field_info as get_annotation_from_field_info,
)
from pydantic.schema import get_flat_models_from_field as get_flat_models_from_field
from pydantic.schema import get_model_name_map as get_model_name_map # noqa: F401
from pydantic.types import SecretBytes as SecretBytes # noqa: F401
from pydantic.types import SecretStr as SecretStr # noqa: F401
from pydantic.typing import evaluate_forwardref as evaluate_forwardref # noqa: F401
from pydantic.utils import lenient_issubclass as lenient_issubclass # noqa: F401
from pydantic.schema import get_model_name_map as get_model_name_map
from pydantic.types import SecretBytes as SecretBytes
from pydantic.types import SecretStr as SecretStr
from pydantic.typing import evaluate_forwardref as evaluate_forwardref
from pydantic.utils import lenient_issubclass as lenient_issubclass
else:
from pydantic.v1 import AnyUrl as Url # noqa: F401
from pydantic.v1 import (
BaseConfig as BaseConfig, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1 import (
BaseModel as BaseModel, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1 import (
ValidationError as ValidationError, # type: ignore[assignment] # noqa: F401
from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]
from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]
from pydantic.v1 import ( # type: ignore[assignment]
ValidationError as ValidationError,
)
from pydantic.v1 import create_model as create_model # noqa: F401
from pydantic.v1.class_validators import Validator as Validator # noqa: F401
from pydantic.v1.color import (
Color as Color, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper # noqa: F401
from pydantic.v1 import create_model as create_model # type: ignore[no-redef]
from pydantic.v1.class_validators import Validator as Validator
from pydantic.v1.color import Color as Color # type: ignore[assignment]
from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper
from pydantic.v1.errors import MissingError
from pydantic.v1.fields import (
SHAPE_FROZENSET,
@ -102,12 +89,12 @@ else:
SHAPE_TUPLE_ELLIPSIS,
)
from pydantic.v1.fields import FieldInfo as FieldInfo # type: ignore[assignment]
from pydantic.v1.fields import ModelField as ModelField # noqa: F401
from pydantic.v1.fields import ModelField as ModelField
from pydantic.v1.fields import Undefined as Undefined
from pydantic.v1.fields import UndefinedType as UndefinedType # noqa: F401
from pydantic.v1.networks import AnyUrl as AnyUrl # noqa: F401
from pydantic.v1.networks import (
NameEmail as NameEmail, # type: ignore[assignment] # noqa: F401
from pydantic.v1.fields import UndefinedType as UndefinedType
from pydantic.v1.networks import AnyUrl as AnyUrl
from pydantic.v1.networks import ( # type: ignore[assignment]
NameEmail as NameEmail,
)
from pydantic.v1.schema import TypeModelSet as TypeModelSet
from pydantic.v1.schema import (
@ -116,30 +103,26 @@ else:
model_process_schema,
)
from pydantic.v1.schema import (
get_annotation_from_field_info as get_annotation_from_field_info, # noqa: F401
)
from pydantic.v1.schema import (
get_flat_models_from_field as get_flat_models_from_field, # noqa: F401
get_annotation_from_field_info as get_annotation_from_field_info,
)
from pydantic.v1.schema import (
get_model_name_map as get_model_name_map, # noqa: F401
get_flat_models_from_field as get_flat_models_from_field,
)
from pydantic.v1.types import (
SecretBytes as SecretBytes, # type: ignore[assignment] # noqa: F401
from pydantic.v1.schema import get_model_name_map as get_model_name_map
from pydantic.v1.types import ( # type: ignore[assignment]
SecretBytes as SecretBytes,
)
from pydantic.v1.types import (
SecretStr as SecretStr, # type: ignore[assignment] # noqa: F401
from pydantic.v1.types import ( # type: ignore[assignment]
SecretStr as SecretStr,
)
from pydantic.v1.typing import (
evaluate_forwardref as evaluate_forwardref, # noqa: F401
)
from pydantic.v1.utils import lenient_issubclass as lenient_issubclass # noqa: F401
from pydantic.v1.typing import evaluate_forwardref as evaluate_forwardref
from pydantic.v1.utils import lenient_issubclass as lenient_issubclass
GetJsonSchemaHandler = Any
JsonSchemaValue = Dict[str, Any]
CoreSchema = Any
Url = AnyUrl
sequence_shapes = {
SHAPE_LIST,

29
fastapi/_compat/v2.py

@ -27,7 +27,7 @@ from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-
)
from pydantic._internal._typing_extra import eval_type_lenient
from pydantic._internal._utils import lenient_issubclass as lenient_issubclass
from pydantic.fields import FieldInfo
from pydantic.fields import FieldInfo as FieldInfo
from pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema
from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
from pydantic_core import CoreSchema as CoreSchema
@ -196,7 +196,7 @@ def get_schema_from_model_field(
def get_definitions(
*,
fields: List[ModelField],
fields: Sequence[ModelField],
model_name_map: ModelNameMap,
separate_input_output_schemas: bool = True,
) -> Tuple[
@ -219,7 +219,7 @@ def get_definitions(
inputs = [
(field, override_mode or field.mode, field._type_adapter.core_schema)
for field in fields + list(unique_flat_model_fields)
for field in list(fields) + list(unique_flat_model_fields)
]
field_mapping, definitions = schema_generator.generate_definitions(inputs=inputs)
for item_def in cast(Dict[str, Dict[str, Any]], definitions).values():
@ -277,25 +277,30 @@ def _remap_definitions_and_field_mappings(
field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
):
) -> Tuple[
Dict[Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
Dict[str, Any],
]:
old_name_to_new_name_map = {}
for key, value in field_mapping.items():
model = key[0].type_
for field_key, schema in field_mapping.items():
model = field_key[0].type_
if model not in model_name_map:
continue
new_name = model_name_map[model]
old_name = value["$ref"].split("/")[-1]
old_name = schema["$ref"].split("/")[-1]
if old_name in {f"{new_name}-Input", f"{new_name}-Output"}:
continue
old_name_to_new_name_map[old_name] = new_name
new_field_mapping = {}
for key, value in field_mapping.items():
new_value = _replace_refs(
schema=value,
new_field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
] = {}
for field_key, schema in field_mapping.items():
new_schema = _replace_refs(
schema=schema,
old_name_to_new_name_map=old_name_to_new_name_map,
)
new_field_mapping[key] = new_value
new_field_mapping[field_key] = new_schema
new_definitions = {}
for key, value in definitions.items():

4
fastapi/encoders.py

@ -220,10 +220,10 @@ def jsonable_encoder(
include = set(include)
if exclude is not None and not isinstance(exclude, (set, dict)):
exclude = set(exclude)
if isinstance(obj, (BaseModel, v1.BaseModel)): # type: ignore[attr-defined]
if isinstance(obj, (BaseModel, v1.BaseModel)):
# TODO: remove when deprecating Pydantic v1
encoders: Dict[Any, Any] = {}
if isinstance(obj, v1.BaseModel): # type: ignore[attr-defined]
if isinstance(obj, v1.BaseModel):
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
if custom_encoder:
encoders = {**encoders, **custom_encoder}

4
fastapi/utils.py

@ -144,10 +144,10 @@ def create_cloned_field(
original_type = original_type.__pydantic_model__
use_type = original_type
if lenient_issubclass(original_type, v1.BaseModel):
original_type = cast(Type[v1.BaseModel], original_type) # type: ignore[name-defined]
original_type = cast(Type[v1.BaseModel], original_type)
use_type = cloned_types.get(original_type)
if use_type is None:
use_type = v1.create_model(original_type.__name__, __base__=original_type) # type: ignore[attr-defined]
use_type = v1.create_model(original_type.__name__, __base__=original_type)
cloned_types[original_type] = use_type
for f in original_type.__fields__.values():
use_type.__fields__[f.name] = create_cloned_field(

Loading…
Cancel
Save