Browse Source

🎨 Tweak types

pull/14168/head
Sebastián Ramírez 10 months ago
parent
commit
3d14dda1c4
  1. 20
      fastapi/_compat/_params_v1.py
  2. 42
      fastapi/_compat/main.py
  3. 12
      fastapi/_compat/shared.py
  4. 128
      fastapi/_compat/v1.py
  5. 4
      fastapi/dependencies/utils.py
  6. 6
      fastapi/encoders.py
  7. 12
      fastapi/utils.py

20
fastapi/_compat/_params_v1.py

@ -5,9 +5,7 @@ from typing import Any, Callable, Dict, List, Optional, Union
from fastapi.openapi.models import Example
from typing_extensions import Annotated, deprecated
from .shared import (
PYDANTIC_VERSION_MINOR_TUPLE,
)
from .shared import PYDANTIC_VERSION_MINOR_TUPLE
from .v1 import FieldInfo, Undefined
_Unset: Any = Undefined
@ -20,7 +18,7 @@ class ParamTypes(Enum):
cookie = "cookie"
class Param(FieldInfo):
class Param(FieldInfo): # type: ignore[misc]
in_: ParamTypes
def __init__(
@ -121,7 +119,7 @@ class Param(FieldInfo):
return f"{self.__class__.__name__}({self.default})"
class Path(Param):
class Path(Param): # type: ignore[misc]
in_ = ParamTypes.path
def __init__(
@ -207,7 +205,7 @@ class Path(Param):
)
class Query(Param):
class Query(Param): # type: ignore[misc]
in_ = ParamTypes.query
def __init__(
@ -291,7 +289,7 @@ class Query(Param):
)
class Header(Param):
class Header(Param): # type: ignore[misc]
in_ = ParamTypes.header
def __init__(
@ -377,7 +375,7 @@ class Header(Param):
)
class Cookie(Param):
class Cookie(Param): # type: ignore[misc]
in_ = ParamTypes.cookie
def __init__(
@ -461,7 +459,7 @@ class Cookie(Param):
)
class Body(FieldInfo):
class Body(FieldInfo): # type: ignore[misc]
def __init__(
self,
default: Any = Undefined,
@ -565,7 +563,7 @@ class Body(FieldInfo):
return f"{self.__class__.__name__}({self.default})"
class Form(Body):
class Form(Body): # type: ignore[misc]
def __init__(
self,
default: Any = Undefined,
@ -649,7 +647,7 @@ class Form(Body):
)
class File(Form):
class File(Form): # type: ignore[misc]
def __init__(
self,
default: Any = Undefined,

42
fastapi/_compat/main.py

@ -48,8 +48,8 @@ else:
@lru_cache
def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]:
if lenient_issubclass(model, v1.BaseModel):
return v1.get_model_fields(model) # type: ignore[return-value]
if lenient_issubclass(model, v1.BaseModel): # type: ignore[attr-defined]
return v1.get_model_fields(model)
else:
from . import v2
@ -67,7 +67,7 @@ def _is_undefined(value: object) -> bool:
def _get_model_config(model: BaseModel) -> Any:
if isinstance(model, v1.BaseModel):
if isinstance(model, v1.BaseModel): # type: ignore[attr-defined]
return v1._get_model_config(model)
elif PYDANTIC_V2:
from . import v2
@ -78,7 +78,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):
if isinstance(model, v1.BaseModel): # type: ignore[attr-defined]
return v1._model_dump(model, mode=mode, **kwargs)
elif PYDANTIC_V2:
from . import v2
@ -110,12 +110,12 @@ def create_body_model(
*, fields: Sequence[ModelField], model_name: str
) -> Type[BaseModel]:
if fields and isinstance(fields[0], v1.ModelField):
return v1.create_body_model(fields=fields, model_name=model_name) # type: ignore[return-value]
return v1.create_body_model(fields=fields, model_name=model_name)
else:
assert PYDANTIC_V2
from . import v2
return v2.create_body_model(fields=fields, model_name=model_name) # type: ignore[return-value]
return v2.create_body_model(fields=fields, model_name=model_name) # type: ignore[arg-type]
def get_annotation_from_field_info(
@ -141,7 +141,7 @@ def is_bytes_field(field: ModelField) -> bool:
assert PYDANTIC_V2
from . import v2
return v2.is_bytes_field(field) # type: ignore[return-value]
return v2.is_bytes_field(field) # type: ignore[arg-type]
def is_bytes_sequence_field(field: ModelField) -> bool:
@ -151,7 +151,7 @@ def is_bytes_sequence_field(field: ModelField) -> bool:
assert PYDANTIC_V2
from . import v2
return v2.is_bytes_sequence_field(field) # type: ignore[return-value]
return v2.is_bytes_sequence_field(field) # type: ignore[arg-type]
def is_scalar_field(field: ModelField) -> bool:
@ -161,7 +161,7 @@ def is_scalar_field(field: ModelField) -> bool:
assert PYDANTIC_V2
from . import v2
return v2.is_scalar_field(field) # type: ignore[return-value]
return v2.is_scalar_field(field) # type: ignore[arg-type]
def is_scalar_sequence_field(field: ModelField) -> bool:
@ -171,7 +171,7 @@ def is_scalar_sequence_field(field: ModelField) -> bool:
assert PYDANTIC_V2
from . import v2
return v2.is_scalar_sequence_field(field) # type: ignore[return-value]
return v2.is_scalar_sequence_field(field) # type: ignore[arg-type]
def is_sequence_field(field: ModelField) -> bool:
@ -181,7 +181,7 @@ def is_sequence_field(field: ModelField) -> bool:
assert PYDANTIC_V2
from . import v2
return v2.is_sequence_field(field) # type: ignore[return-value]
return v2.is_sequence_field(field) # type: ignore[arg-type]
def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
@ -191,11 +191,11 @@ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
assert PYDANTIC_V2
from . import v2
return v2.serialize_sequence_value(field=field, value=value) # type: ignore[return-value]
return v2.serialize_sequence_value(field=field, value=value) # type: ignore[arg-type]
def _model_rebuild(model: Type[BaseModel]) -> None:
if lenient_issubclass(model, v1.BaseModel):
if lenient_issubclass(model, v1.BaseModel): # type: ignore[attr-defined]
v1._model_rebuild(model)
elif PYDANTIC_V2:
from . import v2
@ -205,7 +205,7 @@ def _model_rebuild(model: Type[BaseModel]) -> None:
def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
v1_model_fields = [field for field in fields if isinstance(field, v1.ModelField)]
v1_flat_models = v1.get_flat_models_from_fields(v1_model_fields, known_models=set())
v1_flat_models = v1.get_flat_models_from_fields(v1_model_fields, known_models=set()) # type: ignore[attr-defined]
all_flat_models = v1_flat_models
if PYDANTIC_V2:
from . import v2
@ -218,10 +218,10 @@ def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
)
all_flat_models = all_flat_models.union(v2_flat_models)
model_name_map = v2.get_model_name_map(all_flat_models) # type: ignore[no-any-return]
model_name_map = v2.get_model_name_map(all_flat_models)
return model_name_map
model_name_map = v1.get_model_name_map(all_flat_models) # type: ignore[no-any-return]
return model_name_map # type: ignore[return-value]
model_name_map = v1.get_model_name_map(all_flat_models)
return model_name_map
def get_definitions(
@ -269,7 +269,7 @@ def get_schema_from_model_field(
return v1.get_schema_from_model_field(
field=field,
model_name_map=model_name_map,
field_mapping=field_mapping, # type: ignore[arg-type]
field_mapping=field_mapping,
separate_input_output_schemas=separate_input_output_schemas,
)
else:
@ -277,7 +277,7 @@ def get_schema_from_model_field(
from . import v2
return v2.get_schema_from_model_field(
field=field,
field=field, # type: ignore[arg-type]
model_name_map=model_name_map,
field_mapping=field_mapping, # type: ignore[arg-type]
separate_input_output_schemas=separate_input_output_schemas,
@ -295,10 +295,10 @@ def _is_model_field(value: Any) -> bool:
def _is_model_class(value: Any) -> bool:
if lenient_issubclass(value, v1.BaseModel):
if lenient_issubclass(value, v1.BaseModel): # type: ignore[attr-defined]
return True
elif PYDANTIC_V2:
from . import v2
return lenient_issubclass(value, v2.BaseModel)
return lenient_issubclass(value, v2.BaseModel) # type: ignore[attr-defined]
return False

12
fastapi/_compat/shared.py

@ -31,10 +31,10 @@ if sys.version_info < (3, 9):
# TODO: remove when dropping support for Python 3.8
WithArgsTypes: Tuple[Any, ...] = ()
elif sys.version_info < (3, 10):
WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # pyright: ignore[reportAttributeAccessIssue]
WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # type: ignore[attr-defined]
else:
WithArgsTypes: tuple[Any, ...] = (
typing._GenericAlias,
typing._GenericAlias, # type: ignore[attr-defined]
types.GenericAlias,
types.UnionType,
) # pyright: ignore[reportAttributeAccessIssue]
@ -77,7 +77,7 @@ def lenient_issubclass(
def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
if lenient_issubclass(annotation, (str, bytes)):
return False
return lenient_issubclass(annotation, sequence_types)
return lenient_issubclass(annotation, sequence_types) # type: ignore[arg-type]
def field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
@ -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))
lenient_issubclass(annotation, (BaseModel, v1.BaseModel, Mapping, UploadFile)) # type: ignore[attr-defined]
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):
if lenient_issubclass(annotation, v1.BaseModel): # type: ignore[attr-defined]
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):
if lenient_issubclass(arg, v1.BaseModel): # type: ignore[attr-defined]
return True
if field_annotation_is_sequence(annotation):
for sub_annotation in get_args(annotation):

128
fastapi/_compat/v1.py

@ -23,20 +23,20 @@ PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")
PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
# Keeping old "Required" functionality from Pydantic V1, without
# shadowing typing.Required.
RequiredParam: Any = Ellipsis # type: ignore[no-redef]
RequiredParam: Any = Ellipsis
if not PYDANTIC_V2:
from pydantic import AnyUrl as Url # noqa: F401
from pydantic import ( # type: ignore[assignment]
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 ( # type: ignore[no-redef]
from pydantic.class_validators import (
Validator as Validator, # noqa: F401
)
from pydantic.color import Color as Color # noqa: F401
from pydantic.error_wrappers import ( # type: ignore[no-redef]
from pydantic.error_wrappers import (
ErrorWrapper as ErrorWrapper, # noqa: F401
)
from pydantic.errors import MissingError
@ -50,14 +50,10 @@ if not PYDANTIC_V2:
SHAPE_TUPLE_ELLIPSIS,
)
from pydantic.fields import FieldInfo as FieldInfo
from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
ModelField as ModelField, # noqa: F401
)
from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
Undefined as Undefined,
)
from pydantic.fields import ( # type: ignore[no-redef, attr-defined]
UndefinedType as UndefinedType, # noqa: F401
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.networks import AnyUrl as AnyUrl # noqa: F401
from pydantic.networks import NameEmail as NameEmail # noqa: F401
@ -67,37 +63,36 @@ if not PYDANTIC_V2:
get_flat_models_from_fields,
model_process_schema,
)
from pydantic.schema import ( # type: ignore[no-redef] # noqa: F401
get_annotation_from_field_info as get_annotation_from_field_info,
from pydantic.schema import (
get_annotation_from_field_info as get_annotation_from_field_info, # noqa: F401
)
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 ( # type: ignore[no-redef]
evaluate_forwardref as evaluate_forwardref, # noqa: F401
)
from pydantic.utils import ( # type: ignore[no-redef]
lenient_issubclass as lenient_issubclass, # noqa: F401
)
from pydantic.typing import evaluate_forwardref as evaluate_forwardref # noqa: F401
from pydantic.utils import lenient_issubclass as lenient_issubclass # noqa: F401
else:
from pydantic.v1 import AnyUrl as Url # noqa: F401
from pydantic.v1 import ( # type: ignore[assignment]
BaseConfig as BaseConfig, # noqa: F401
from pydantic.v1 import (
BaseConfig as BaseConfig, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1 import BaseModel, create_model
from pydantic.v1 import ValidationError as ValidationError # noqa: F401
from pydantic.v1.class_validators import ( # type: ignore[no-redef]
Validator as Validator, # noqa: F401
from pydantic.v1 import (
BaseModel as BaseModel, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1.color import Color as Color # noqa: F401
from pydantic.v1.error_wrappers import ( # type: ignore[no-redef]
ErrorWrapper as ErrorWrapper, # noqa: F401
from pydantic.v1 import (
ValidationError as ValidationError, # type: ignore[assignment] # noqa: F401
)
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.errors import MissingError
from pydantic.v1.fields import ( # type: ignore[attr-defined]
from pydantic.v1.fields import (
SHAPE_FROZENSET,
SHAPE_LIST,
SHAPE_SEQUENCE,
@ -106,26 +101,22 @@ else:
SHAPE_TUPLE,
SHAPE_TUPLE_ELLIPSIS,
)
from pydantic.v1.fields import FieldInfo as FieldInfo
from pydantic.v1.fields import ( # type: ignore[no-redef,attr-defined]
ModelField as ModelField, # noqa: F401
)
from pydantic.v1.fields import ( # type: ignore[no-redef,attr-defined]
Undefined as Undefined,
)
from pydantic.v1.fields import ( # type: ignore[no-redef, attr-defined]
UndefinedType as UndefinedType, # noqa: F401
)
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 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 # noqa: F401
from pydantic.v1.networks import (
NameEmail as NameEmail, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1.schema import TypeModelSet as TypeModelSet
from pydantic.v1.schema import (
field_schema,
get_flat_models_from_fields,
model_process_schema,
)
from pydantic.v1.schema import ( # type: ignore[no-redef] # noqa: F401
get_annotation_from_field_info as get_annotation_from_field_info,
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
@ -133,19 +124,21 @@ else:
from pydantic.v1.schema import (
get_model_name_map as get_model_name_map, # noqa: F401
)
from pydantic.v1.types import SecretBytes as SecretBytes # noqa: F401
from pydantic.v1.types import SecretStr as SecretStr # noqa: F401
from pydantic.v1.typing import ( # type: ignore[no-redef]
evaluate_forwardref as evaluate_forwardref, # noqa: F401
from pydantic.v1.types import (
SecretBytes as SecretBytes, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1.utils import ( # type: ignore[no-redef]
lenient_issubclass as lenient_issubclass, # noqa: F401
from pydantic.v1.types import (
SecretStr as SecretStr, # type: ignore[assignment] # noqa: F401
)
from pydantic.v1.typing import (
evaluate_forwardref as evaluate_forwardref, # noqa: F401
)
from pydantic.v1.utils import lenient_issubclass as lenient_issubclass # noqa: F401
GetJsonSchemaHandler = Any # type: ignore[assignment,misc]
JsonSchemaValue = Dict[str, Any] # type: ignore[misc]
CoreSchema = Any # type: ignore[assignment,misc]
GetJsonSchemaHandler = Any
JsonSchemaValue = Dict[str, Any]
CoreSchema = Any
sequence_shapes = {
@ -166,18 +159,18 @@ sequence_shape_to_type = {
@dataclass
class GenerateJsonSchema: # type: ignore[no-redef]
class GenerateJsonSchema:
ref_template: str
class PydanticSchemaGenerationError(Exception): # type: ignore[no-redef]
class PydanticSchemaGenerationError(Exception):
pass
RequestErrorModel: Type[BaseModel] = create_model("Request")
def with_info_plain_validator_function( # type: ignore[misc]
def with_info_plain_validator_function(
function: Callable[..., Any],
*,
ref: Union[str, None] = None,
@ -211,7 +204,7 @@ def is_pv1_scalar_field(field: ModelField) -> bool:
field_info = field.field_info
if not (
field.shape == SHAPE_SINGLETON # type: ignore[attr-defined]
field.shape == SHAPE_SINGLETON
and not lenient_issubclass(field.type_, BaseModel)
and not lenient_issubclass(field.type_, dict)
and not shared.field_annotation_is_sequence(field.type_)
@ -219,21 +212,18 @@ def is_pv1_scalar_field(field: ModelField) -> bool:
and not isinstance(field_info, params.Body)
):
return False
if field.sub_fields: # type: ignore[attr-defined]
if not all(
is_pv1_scalar_field(f)
for f in field.sub_fields # type: ignore[attr-defined]
):
if field.sub_fields:
if not all(is_pv1_scalar_field(f) for f in field.sub_fields):
return False
return True
def is_pv1_scalar_sequence_field(field: ModelField) -> bool:
if (field.shape in sequence_shapes) and not lenient_issubclass( # type: ignore[attr-defined]
if (field.shape in sequence_shapes) and not lenient_issubclass(
field.type_, BaseModel
):
if field.sub_fields is not None: # type: ignore[attr-defined]
for sub_field in field.sub_fields: # type: ignore[attr-defined]
if field.sub_fields is not None:
for sub_field in field.sub_fields:
if not is_pv1_scalar_field(sub_field):
return False
return True
@ -319,7 +309,7 @@ def is_scalar_field(field: ModelField) -> bool:
def is_sequence_field(field: ModelField) -> bool:
return field.shape in sequence_shapes or shared._annotation_is_sequence(field.type_) # type: ignore[attr-defined]
return field.shape in sequence_shapes or shared._annotation_is_sequence(field.type_)
def is_scalar_sequence_field(field: ModelField) -> bool:
@ -327,11 +317,11 @@ def is_scalar_sequence_field(field: ModelField) -> bool:
def is_bytes_field(field: ModelField) -> bool:
return lenient_issubclass(field.type_, bytes)
return lenient_issubclass(field.type_, bytes) # type: ignore[no-any-return]
def is_bytes_sequence_field(field: ModelField) -> bool:
return field.shape in sequence_shapes and lenient_issubclass(field.type_, bytes) # type: ignore[attr-defined]
return field.shape in sequence_shapes and lenient_issubclass(field.type_, bytes)
def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
@ -339,11 +329,11 @@ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
return sequence_shape_to_type[field.shape](value) # type: ignore[no-any-return,attr-defined]
return sequence_shape_to_type[field.shape](value) # type: ignore[no-any-return]
def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
missing_field_error = ErrorWrapper(MissingError(), loc=loc) # type: ignore[call-arg]
missing_field_error = ErrorWrapper(MissingError(), loc=loc)
new_error = ValidationError([missing_field_error], RequestErrorModel)
return new_error.errors()[0] # type: ignore[return-value]

4
fastapi/dependencies/utils.py

@ -733,7 +733,7 @@ def _validate_value_with_model_field(
else:
return deepcopy(field.default), []
v_, errors_ = field.validate(value, values, loc=loc)
if _is_error_wrapper(errors_):
if _is_error_wrapper(errors_): # type: ignore[arg-type]
return None, [errors_]
elif isinstance(errors_, list):
new_errors = v1._regenerate_error_with_loc(errors=errors_, loc_prefix=())
@ -1015,7 +1015,7 @@ def get_body_field(
BodyFieldInfo = params.Form
else:
if annotation_is_pydantic_v1(BodyModel):
BodyFieldInfo = _params_v1.Body
BodyFieldInfo = _params_v1.Body # type: ignore[assignment]
else:
BodyFieldInfo = params.Body

6
fastapi/encoders.py

@ -86,7 +86,7 @@ ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
set: list,
UUID: str,
Url: str,
v1.Url: str,
v1.Url: str, # type: ignore[attr-defined]
AnyUrl: str,
v1.AnyUrl: str,
}
@ -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)):
if isinstance(obj, (BaseModel, v1.BaseModel)): # type: ignore[attr-defined]
# TODO: remove when deprecating Pydantic v1
encoders: Dict[Any, Any] = {}
if isinstance(obj, v1.BaseModel):
if isinstance(obj, v1.BaseModel): # type: ignore[attr-defined]
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
if custom_encoder:
encoders = {**encoders, **custom_encoder}

12
fastapi/utils.py

@ -102,7 +102,7 @@ def create_model_field(
if annotation_is_pydantic_v1(type_) or version == "1":
try:
return v1.ModelField(**v1_kwargs) # type: ignore[arg-type]
return v1.ModelField(**v1_kwargs) # type: ignore[no-any-return]
except RuntimeError:
raise fastapi.exceptions.FastAPIError(_invalid_args_message) from None
elif PYDANTIC_V2:
@ -113,13 +113,13 @@ def create_model_field(
)
kwargs = {"mode": mode, "name": name, "field_info": field_info}
try:
return v2.ModelField(**kwargs) # type: ignore[arg-type]
return v2.ModelField(**kwargs) # type: ignore[return-value,arg-type]
except PydanticSchemaGenerationError:
raise fastapi.exceptions.FastAPIError(_invalid_args_message) from None
# Pydantic v2 is not installed, but it's not a Pydantic v1 ModelField, it could be
# a Pydantic v1 type, like a constrained int
try:
return v1.ModelField(**v1_kwargs) # type: ignore[arg-type]
return v1.ModelField(**v1_kwargs) # type: ignore[no-any-return]
except RuntimeError:
raise fastapi.exceptions.FastAPIError(_invalid_args_message) from None
@ -132,7 +132,7 @@ def create_cloned_field(
if PYDANTIC_V2:
from ._compat import v2
if isinstance(field, v2.ModelField): # type: ignore[name-defined]
if isinstance(field, v2.ModelField):
return field
# cloned_types caches already cloned types to support recursive models and improve
# performance by avoiding unnecessary cloning
@ -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)
original_type = cast(Type[v1.BaseModel], original_type) # type: ignore[name-defined]
use_type = cloned_types.get(original_type)
if use_type is None:
use_type = v1.create_model(original_type.__name__, __base__=original_type)
use_type = v1.create_model(original_type.__name__, __base__=original_type) # type: ignore[attr-defined]
cloned_types[original_type] = use_type
for f in original_type.__fields__.values():
use_type.__fields__[f.name] = create_cloned_field(

Loading…
Cancel
Save