From 3d14dda1c4ce0de72f636da23e9d0c78550fdcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 8 Oct 2025 22:33:23 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Tweak=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/_compat/_params_v1.py | 20 +++--- fastapi/_compat/main.py | 42 +++++------ fastapi/_compat/shared.py | 12 ++-- fastapi/_compat/v1.py | 128 ++++++++++++++++------------------ fastapi/dependencies/utils.py | 4 +- fastapi/encoders.py | 6 +- fastapi/utils.py | 12 ++-- 7 files changed, 106 insertions(+), 118 deletions(-) diff --git a/fastapi/_compat/_params_v1.py b/fastapi/_compat/_params_v1.py index b16677e5c..805bd65d6 100644 --- a/fastapi/_compat/_params_v1.py +++ b/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, diff --git a/fastapi/_compat/main.py b/fastapi/_compat/main.py index 42375658e..94008d9a0 100644 --- a/fastapi/_compat/main.py +++ b/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 diff --git a/fastapi/_compat/shared.py b/fastapi/_compat/shared.py index b7bad16bf..50c847d4e 100644 --- a/fastapi/_compat/shared.py +++ b/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): diff --git a/fastapi/_compat/v1.py b/fastapi/_compat/v1.py index 4c941873b..bf20d81bf 100644 --- a/fastapi/_compat/v1.py +++ b/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] diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 6537b9305..e07d1ef88 100644 --- a/fastapi/dependencies/utils.py +++ b/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 diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 8ff7d58dd..b8b6f400a 100644 --- a/fastapi/encoders.py +++ b/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} diff --git a/fastapi/utils.py b/fastapi/utils.py index f8375bc8e..eb9691682 100644 --- a/fastapi/utils.py +++ b/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(