]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
⬆ Require Pydantic > 1.0 (#1862)
authorSebastián Ramírez <tiangolo@gmail.com>
Sun, 9 Aug 2020 20:17:08 +0000 (22:17 +0200)
committerGitHub <noreply@github.com>
Sun, 9 Aug 2020 20:17:08 +0000 (22:17 +0200)
* 🔥 Remove support for Pydantic < 1.0

* 🔥 Remove deprecated skip_defaults from jsonable_encoder and set default for exclude to None, as in Pydantic

* ♻️ Set default of response_model_exclude=None as in Pydantic

* ⬆️ Require Pydantic >=1.0.0 in requirements

14 files changed:
fastapi/applications.py
fastapi/dependencies/models.py
fastapi/dependencies/utils.py
fastapi/encoders.py
fastapi/exceptions.py
fastapi/openapi/models.py
fastapi/openapi/utils.py
fastapi/params.py
fastapi/requests.py
fastapi/routing.py
fastapi/utils.py
pyproject.toml
tests/test_jsonable_encoder.py
tests/test_tutorial/test_body_fields/test_tutorial001.py

index 27a72fe314e76010e57759ddf446bee79e51a797..f3ce08e9f23751b9e652ea338d810c5d7d764059 100644 (file)
@@ -16,7 +16,6 @@ from fastapi.openapi.docs import (
 )
 from fastapi.openapi.utils import get_openapi
 from fastapi.params import Depends
-from fastapi.utils import warning_response_model_skip_defaults_deprecated
 from starlette.applications import Starlette
 from starlette.datastructures import State
 from starlette.exceptions import HTTPException
@@ -198,9 +197,8 @@ class FastAPI(Starlette):
         methods: Optional[List[str]] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -208,8 +206,6 @@ class FastAPI(Starlette):
         response_class: Optional[Type[Response]] = None,
         name: Optional[str] = None,
     ) -> None:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         self.router.add_api_route(
             path,
             endpoint=endpoint,
@@ -227,9 +223,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -253,9 +247,8 @@ class FastAPI(Starlette):
         methods: Optional[List[str]] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -263,9 +256,6 @@ class FastAPI(Starlette):
         response_class: Optional[Type[Response]] = None,
         name: Optional[str] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
-
         def decorator(func: Callable) -> Callable:
             self.router.add_api_route(
                 path,
@@ -284,9 +274,7 @@ class FastAPI(Starlette):
                 response_model_include=response_model_include,
                 response_model_exclude=response_model_exclude,
                 response_model_by_alias=response_model_by_alias,
-                response_model_exclude_unset=bool(
-                    response_model_exclude_unset or response_model_skip_defaults
-                ),
+                response_model_exclude_unset=response_model_exclude_unset,
                 response_model_exclude_defaults=response_model_exclude_defaults,
                 response_model_exclude_none=response_model_exclude_none,
                 include_in_schema=include_in_schema,
@@ -344,9 +332,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -355,8 +342,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.get(
             path,
             response_model=response_model,
@@ -372,9 +357,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -398,9 +381,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -409,8 +391,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.put(
             path,
             response_model=response_model,
@@ -426,9 +406,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -452,9 +430,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -463,8 +440,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.post(
             path,
             response_model=response_model,
@@ -480,9 +455,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -506,9 +479,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -517,8 +489,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.delete(
             path,
             response_model=response_model,
@@ -534,9 +504,7 @@ class FastAPI(Starlette):
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
             operation_id=operation_id,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -560,9 +528,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -571,8 +538,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.options(
             path,
             response_model=response_model,
@@ -588,9 +553,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -614,9 +577,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -625,8 +587,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.head(
             path,
             response_model=response_model,
@@ -642,9 +602,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -668,9 +626,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -679,8 +636,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.patch(
             path,
             response_model=response_model,
@@ -696,9 +651,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -722,9 +675,8 @@ class FastAPI(Starlette):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -733,8 +685,6 @@ class FastAPI(Starlette):
         name: Optional[str] = None,
         callbacks: Optional[List[routing.APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.router.trace(
             path,
             response_model=response_model,
@@ -750,9 +700,7 @@ class FastAPI(Starlette):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
index 8e0c7830a8c91948d4174801903f0b88cb9eeb2b..5aff1de3ba28dce9421e3a992b45a51e33cdf5e4 100644 (file)
@@ -1,12 +1,7 @@
 from typing import Callable, List, Optional, Sequence
 
 from fastapi.security.base import SecurityBase
-
-try:
-    from pydantic.fields import ModelField
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic.fields import Field as ModelField  # type: ignore
+from pydantic.fields import ModelField
 
 param_supported_types = (str, int, float, bool)
 
index 6c49941ad4a389488fa0016b54a2693f5b9b2b07..7c9f7e8471312ad7053a80a8254bcca5619d6e39 100644 (file)
@@ -28,15 +28,23 @@ from fastapi.logger import logger
 from fastapi.security.base import SecurityBase
 from fastapi.security.oauth2 import OAuth2, SecurityScopes
 from fastapi.security.open_id_connect_url import OpenIdConnect
-from fastapi.utils import (
-    PYDANTIC_1,
-    create_response_field,
-    get_field_info,
-    get_path_param_names,
-)
-from pydantic import BaseConfig, BaseModel, create_model
+from fastapi.utils import create_response_field, get_path_param_names
+from pydantic import BaseModel, create_model
 from pydantic.error_wrappers import ErrorWrapper
 from pydantic.errors import MissingError
+from pydantic.fields import (
+    SHAPE_LIST,
+    SHAPE_SEQUENCE,
+    SHAPE_SET,
+    SHAPE_SINGLETON,
+    SHAPE_TUPLE,
+    SHAPE_TUPLE_ELLIPSIS,
+    FieldInfo,
+    ModelField,
+    Required,
+)
+from pydantic.schema import get_annotation_from_field_info
+from pydantic.typing import ForwardRef, evaluate_forwardref
 from pydantic.utils import lenient_issubclass
 from starlette.background import BackgroundTasks
 from starlette.concurrency import run_in_threadpool
@@ -45,41 +53,6 @@ from starlette.requests import HTTPConnection, Request
 from starlette.responses import Response
 from starlette.websockets import WebSocket
 
-try:
-    from pydantic.fields import (
-        SHAPE_LIST,
-        SHAPE_SEQUENCE,
-        SHAPE_SET,
-        SHAPE_SINGLETON,
-        SHAPE_TUPLE,
-        SHAPE_TUPLE_ELLIPSIS,
-        FieldInfo,
-        ModelField,
-        Required,
-    )
-    from pydantic.schema import get_annotation_from_field_info
-    from pydantic.typing import ForwardRef, evaluate_forwardref
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic import Schema as FieldInfo  # type: ignore
-    from pydantic.fields import Field as ModelField  # type: ignore
-    from pydantic.fields import Required, Shape  # type: ignore
-    from pydantic.schema import get_annotation_from_schema  # type: ignore
-    from pydantic.utils import ForwardRef, evaluate_forwardref  # type: ignore
-
-    SHAPE_LIST = Shape.LIST
-    SHAPE_SEQUENCE = Shape.SEQUENCE
-    SHAPE_SET = Shape.SET
-    SHAPE_SINGLETON = Shape.SINGLETON
-    SHAPE_TUPLE = Shape.TUPLE
-    SHAPE_TUPLE_ELLIPSIS = Shape.TUPLE_ELLIPS
-
-    def get_annotation_from_field_info(
-        annotation: Any, field_info: FieldInfo, field_name: str
-    ) -> Type[Any]:
-        return get_annotation_from_schema(annotation, field_info)
-
-
 sequence_shapes = {
     SHAPE_LIST,
     SHAPE_SET,
@@ -113,7 +86,7 @@ multipart_incorrect_install_error = (
 
 
 def check_file_field(field: ModelField) -> None:
-    field_info = get_field_info(field)
+    field_info = field.field_info
     if isinstance(field_info, params.Form):
         try:
             # __version__ is available in both multiparts, and can be mocked
@@ -239,7 +212,7 @@ def get_flat_params(dependant: Dependant) -> List[ModelField]:
 
 
 def is_scalar_field(field: ModelField) -> bool:
-    field_info = get_field_info(field)
+    field_info = field.field_info
     if not (
         field.shape == SHAPE_SINGLETON
         and not lenient_issubclass(field.type_, BaseModel)
@@ -354,7 +327,7 @@ def get_dependant(
         ) and is_scalar_sequence_field(param_field):
             add_param_to_fields(field=param_field, dependant=dependant)
         else:
-            field_info = get_field_info(param_field)
+            field_info = param_field.field_info
             assert isinstance(
                 field_info, params.Body
             ), f"Param: {param_field.name} can only be a request body, using Body(...)"
@@ -430,16 +403,13 @@ def get_param_field(
     )
     field.required = required
     if not had_schema and not is_scalar_field(field=field):
-        if PYDANTIC_1:
-            field.field_info = params.Body(field_info.default)
-        else:
-            field.schema = params.Body(field_info.default)  # type: ignore  # pragma: nocover
+        field.field_info = params.Body(field_info.default)
 
     return field
 
 
 def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
-    field_info = cast(params.Param, get_field_info(field))
+    field_info = cast(params.Param, field.field_info)
     if field_info.in_ == params.ParamTypes.path:
         dependant.path_params.append(field)
     elif field_info.in_ == params.ParamTypes.query:
@@ -642,26 +612,17 @@ def request_params_to_args(
             value = received_params.getlist(field.alias) or field.default
         else:
             value = received_params.get(field.alias)
-        field_info = get_field_info(field)
+        field_info = field.field_info
         assert isinstance(
             field_info, params.Param
         ), "Params must be subclasses of Param"
         if value is None:
             if field.required:
-                if PYDANTIC_1:
-                    errors.append(
-                        ErrorWrapper(
-                            MissingError(), loc=(field_info.in_.value, field.alias)
-                        )
-                    )
-                else:  # pragma: nocover
-                    errors.append(
-                        ErrorWrapper(  # type: ignore
-                            MissingError(),
-                            loc=(field_info.in_.value, field.alias),
-                            config=BaseConfig,
-                        )
+                errors.append(
+                    ErrorWrapper(
+                        MissingError(), loc=(field_info.in_.value, field.alias)
                     )
+                )
             else:
                 values[field.name] = deepcopy(field.default)
             continue
@@ -685,7 +646,7 @@ async def request_body_to_args(
     errors = []
     if required_params:
         field = required_params[0]
-        field_info = get_field_info(field)
+        field_info = field.field_info
         embed = getattr(field_info, "embed", None)
         field_alias_omitted = len(required_params) == 1 and not embed
         if field_alias_omitted:
@@ -752,12 +713,7 @@ async def request_body_to_args(
 
 
 def get_missing_field_error(loc: Tuple[str, ...]) -> ErrorWrapper:
-    if PYDANTIC_1:
-        missing_field_error = ErrorWrapper(MissingError(), loc=loc)
-    else:  # pragma: no cover
-        missing_field_error = ErrorWrapper(  # type: ignore
-            MissingError(), loc=loc, config=BaseConfig,
-        )
+    missing_field_error = ErrorWrapper(MissingError(), loc=loc)
     return missing_field_error
 
 
@@ -775,7 +731,7 @@ def get_schema_compatible_field(*, field: ModelField) -> ModelField:
             default=field.default,
             required=field.required,
             alias=field.alias,
-            field_info=get_field_info(field),
+            field_info=field.field_info,
         )
     return out_field
 
@@ -785,7 +741,7 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]:
     if not flat_dependant.body_params:
         return None
     first_param = flat_dependant.body_params[0]
-    field_info = get_field_info(first_param)
+    field_info = first_param.field_info
     embed = getattr(field_info, "embed", None)
     body_param_names_set = {param.name for param in flat_dependant.body_params}
     if len(body_param_names_set) == 1 and not embed:
@@ -796,7 +752,7 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]:
     # in case a sub-dependency is evaluated with a single unique body field
     # That is combined (embedded) with other body fields
     for param in flat_dependant.body_params:
-        setattr(get_field_info(param), "embed", True)
+        setattr(param.field_info, "embed", True)
     model_name = "Body_" + name
     BodyModel = create_model(model_name)
     for f in flat_dependant.body_params:
@@ -804,21 +760,17 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]:
     required = any(True for f in flat_dependant.body_params if f.required)
 
     BodyFieldInfo_kwargs: Dict[str, Any] = dict(default=None)
-    if any(
-        isinstance(get_field_info(f), params.File) for f in flat_dependant.body_params
-    ):
+    if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params):
         BodyFieldInfo: Type[params.Body] = params.File
-    elif any(
-        isinstance(get_field_info(f), params.Form) for f in flat_dependant.body_params
-    ):
+    elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
         BodyFieldInfo = params.Form
     else:
         BodyFieldInfo = params.Body
 
         body_param_media_types = [
-            getattr(get_field_info(f), "media_type")
+            getattr(f.field_info, "media_type")
             for f in flat_dependant.body_params
-            if isinstance(get_field_info(f), params.Body)
+            if isinstance(f.field_info, params.Body)
         ]
         if len(set(body_param_media_types)) == 1:
             BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0]
index d0d094b6a6b3aade6f0950b9d301b4b4a06c0a00..1255b74977e3be1a184a381c2e63449428aad50d 100644 (file)
@@ -4,8 +4,6 @@ from pathlib import PurePath
 from types import GeneratorType
 from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
 
-from fastapi.logger import logger
-from fastapi.utils import PYDANTIC_1
 from pydantic import BaseModel
 from pydantic.json import ENCODERS_BY_TYPE
 
@@ -28,21 +26,14 @@ encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
 def jsonable_encoder(
     obj: Any,
     include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-    exclude: Union[SetIntStr, DictIntStrAny] = set(),
+    exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
     by_alias: bool = True,
-    skip_defaults: Optional[bool] = None,
     exclude_unset: bool = False,
     exclude_defaults: bool = False,
     exclude_none: bool = False,
     custom_encoder: dict = {},
     sqlalchemy_safe: bool = True,
 ) -> Any:
-    if skip_defaults is not None:
-        logger.warning(  # pragma: nocover
-            "skip_defaults in jsonable_encoder has been deprecated in favor of "
-            "exclude_unset to keep in line with Pydantic v1, support for it will be "
-            "removed soon."
-        )
     if include is not None and not isinstance(include, set):
         include = set(include)
     if exclude is not None and not isinstance(exclude, set):
@@ -51,24 +42,14 @@ def jsonable_encoder(
         encoder = getattr(obj.__config__, "json_encoders", {})
         if custom_encoder:
             encoder.update(custom_encoder)
-        if PYDANTIC_1:
-            obj_dict = obj.dict(
-                include=include,
-                exclude=exclude,
-                by_alias=by_alias,
-                exclude_unset=bool(exclude_unset or skip_defaults),
-                exclude_none=exclude_none,
-                exclude_defaults=exclude_defaults,
-            )
-        else:  # pragma: nocover
-            if exclude_defaults:
-                raise ValueError("Cannot use exclude_defaults")
-            obj_dict = obj.dict(
-                include=include,
-                exclude=exclude,
-                by_alias=by_alias,
-                skip_defaults=bool(exclude_unset or skip_defaults),
-            )
+        obj_dict = obj.dict(
+            include=include,
+            exclude=exclude,
+            by_alias=by_alias,
+            exclude_unset=exclude_unset,
+            exclude_none=exclude_none,
+            exclude_defaults=exclude_defaults,
+        )
         if "__root__" in obj_dict:
             obj_dict = obj_dict["__root__"]
         return jsonable_encoder(
@@ -94,7 +75,7 @@ def jsonable_encoder(
                     or (not key.startswith("_sa"))
                 )
                 and (value is not None or not exclude_none)
-                and ((include and key in include) or key not in exclude)
+                and ((include and key in include) or not exclude or key not in exclude)
             ):
                 encoded_key = jsonable_encoder(
                     key,
index d7da2030f5a3ee898205c8e4a7086d86f423a381..8d92311d49f561b56794dcda2ddb35866754a44f 100644 (file)
@@ -1,11 +1,8 @@
 from typing import Any, Dict, Optional, Sequence
 
-from fastapi.utils import PYDANTIC_1
 from pydantic import ValidationError, create_model
 from pydantic.error_wrappers import ErrorList
 from starlette.exceptions import HTTPException as StarletteHTTPException
-from starlette.requests import Request
-from starlette.websockets import WebSocket
 
 
 class HTTPException(StarletteHTTPException):
@@ -32,15 +29,9 @@ class FastAPIError(RuntimeError):
 class RequestValidationError(ValidationError):
     def __init__(self, errors: Sequence[ErrorList], *, body: Any = None) -> None:
         self.body = body
-        if PYDANTIC_1:
-            super().__init__(errors, RequestErrorModel)
-        else:
-            super().__init__(errors, Request)  # type: ignore  # pragma: nocover
+        super().__init__(errors, RequestErrorModel)
 
 
 class WebSocketRequestValidationError(ValidationError):
     def __init__(self, errors: Sequence[ErrorList]) -> None:
-        if PYDANTIC_1:
-            super().__init__(errors, WebSocketErrorModel)
-        else:
-            super().__init__(errors, WebSocket)  # type: ignore  # pragma: nocover
+        super().__init__(errors, WebSocketErrorModel)
index 809286327d59355f6b78fbc1fade4edbdc9d85a4..3b716766d055c862456dccaba4e12480958c55c7 100644 (file)
@@ -2,24 +2,13 @@ from enum import Enum
 from typing import Any, Callable, Dict, Iterable, List, Optional, Union
 
 from fastapi.logger import logger
-from pydantic import BaseModel
-
-try:
-    from pydantic import AnyUrl, Field
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic import Schema as Field  # type: ignore
-    from pydantic import UrlStr as AnyUrl  # type: ignore
+from pydantic import AnyUrl, BaseModel, Field
 
 try:
     import email_validator
 
     assert email_validator  # make autoflake ignore the unused import
-    try:
-        from pydantic import EmailStr
-    except ImportError:  # pragma: nocover
-        # TODO: remove when removing support for Pydantic < 1.0.0
-        from pydantic.types import EmailStr  # type: ignore
+    from pydantic import EmailStr
 except ImportError:  # pragma: no cover
 
     class EmailStr(str):  # type: ignore
index c5e38e993528e67cacc6b881a4645f58c8d0a325..cd1b1baad0206149e3502ca5758bd09842cda8e5 100644 (file)
@@ -16,10 +16,10 @@ from fastapi.params import Body, Param
 from fastapi.utils import (
     deep_dict_update,
     generate_operation_id_for_path,
-    get_field_info,
     get_model_definitions,
 )
 from pydantic import BaseModel
+from pydantic.fields import ModelField
 from pydantic.schema import (
     field_schema,
     get_flat_models_from_fields,
@@ -30,12 +30,6 @@ from starlette.responses import JSONResponse
 from starlette.routing import BaseRoute
 from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
 
-try:
-    from pydantic.fields import ModelField
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic.fields import Field as ModelField  # type: ignore
-
 validation_error_definition = {
     "title": "ValidationError",
     "type": "object",
@@ -91,7 +85,7 @@ def get_openapi_operation_parameters(
 ) -> List[Dict[str, Any]]:
     parameters = []
     for param in all_route_params:
-        field_info = get_field_info(param)
+        field_info = param.field_info
         field_info = cast(Param, field_info)
         # ignore mypy error until enum schemas are released
         parameter = {
@@ -122,7 +116,7 @@ def get_openapi_operation_request_body(
     body_schema, _, _ = field_schema(
         body_field, model_name_map=model_name_map, ref_prefix=REF_PREFIX  # type: ignore
     )
-    field_info = cast(Body, get_field_info(body_field))
+    field_info = cast(Body, body_field.field_info)
     request_media_type = field_info.media_type
     required = body_field.required
     request_body_oai: Dict[str, Any] = {}
index aaa64ceba70c920de5c5e14c3762701c5084bcf5..f53e2dba982c5bf3b76bb8752a471db1ec22a103 100644 (file)
@@ -1,11 +1,7 @@
 from enum import Enum
 from typing import Any, Callable, Optional, Sequence
 
-try:
-    from pydantic.fields import FieldInfo
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic import Schema as FieldInfo  # type: ignore
+from pydantic.fields import FieldInfo
 
 
 class ParamTypes(Enum):
index 06d8f01ccfb4d8af65353e2db331ef1de50b6ce0..d16552c0a9535e1c0bd7f701987301681832eba5 100644 (file)
@@ -1 +1,2 @@
-from starlette.requests import HTTPConnection, Request  # noqa
+from starlette.requests import HTTPConnection as HTTPConnection  # noqa: F401
+from starlette.requests import Request as Request  # noqa: F401
index 0128b33ceb7a827cf9869a6e4d784eca10a50649..e455f81c9538749ce1cb407c8e7d2c035e3728d7 100644 (file)
@@ -16,15 +16,13 @@ from fastapi.encoders import DictIntStrAny, SetIntStr, jsonable_encoder
 from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
 from fastapi.openapi.constants import STATUS_CODES_WITH_NO_BODY
 from fastapi.utils import (
-    PYDANTIC_1,
     create_cloned_field,
     create_response_field,
     generate_operation_id_for_path,
-    get_field_info,
-    warning_response_model_skip_defaults_deprecated,
 )
 from pydantic import BaseModel
 from pydantic.error_wrappers import ErrorWrapper, ValidationError
+from pydantic.fields import ModelField
 from starlette import routing
 from starlette.concurrency import run_in_threadpool
 from starlette.exceptions import HTTPException
@@ -41,12 +39,6 @@ from starlette.status import WS_1008_POLICY_VIOLATION
 from starlette.types import ASGIApp
 from starlette.websockets import WebSocket
 
-try:
-    from pydantic.fields import ModelField
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic.fields import Field as ModelField  # type: ignore
-
 
 def _prepare_response_content(
     res: Any,
@@ -56,17 +48,12 @@ def _prepare_response_content(
     exclude_none: bool = False,
 ) -> Any:
     if isinstance(res, BaseModel):
-        if PYDANTIC_1:
-            return res.dict(
-                by_alias=True,
-                exclude_unset=exclude_unset,
-                exclude_defaults=exclude_defaults,
-                exclude_none=exclude_none,
-            )
-        else:
-            return res.dict(
-                by_alias=True, skip_defaults=exclude_unset,
-            )  # pragma: nocover
+        return res.dict(
+            by_alias=True,
+            exclude_unset=exclude_unset,
+            exclude_defaults=exclude_defaults,
+            exclude_none=exclude_none,
+        )
     elif isinstance(res, list):
         return [
             _prepare_response_content(
@@ -95,7 +82,7 @@ async def serialize_response(
     field: Optional[ModelField] = None,
     response_content: Any,
     include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-    exclude: Union[SetIntStr, DictIntStrAny] = set(),
+    exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
     by_alias: bool = True,
     exclude_unset: bool = False,
     exclude_defaults: bool = False,
@@ -155,7 +142,7 @@ def get_request_handler(
     response_class: Type[Response] = JSONResponse,
     response_field: Optional[ModelField] = None,
     response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-    response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+    response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
     response_model_by_alias: bool = True,
     response_model_exclude_unset: bool = False,
     response_model_exclude_defaults: bool = False,
@@ -164,7 +151,7 @@ def get_request_handler(
 ) -> Callable:
     assert dependant.call is not None, "dependant.call must be a function"
     is_coroutine = asyncio.iscoroutinefunction(dependant.call)
-    is_body_form = body_field and isinstance(get_field_info(body_field), params.Form)
+    is_body_form = body_field and isinstance(body_field.field_info, params.Form)
 
     async def app(request: Request) -> Response:
         try:
@@ -284,7 +271,7 @@ class APIRoute(routing.Route):
         methods: Optional[Union[Set[str], List[str]]] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
@@ -437,9 +424,8 @@ class APIRouter(routing.Router):
         methods: Optional[Union[Set[str], List[str]]] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -449,8 +435,6 @@ class APIRouter(routing.Router):
         route_class_override: Optional[Type[APIRoute]] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> None:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         route_class = route_class_override or self.route_class
         route = route_class(
             path,
@@ -469,9 +453,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -498,9 +480,8 @@ class APIRouter(routing.Router):
         methods: Optional[List[str]] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -509,9 +490,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
-
         def decorator(func: Callable) -> Callable:
             self.add_api_route(
                 path,
@@ -530,9 +508,7 @@ class APIRouter(routing.Router):
                 response_model_include=response_model_include,
                 response_model_exclude=response_model_exclude,
                 response_model_by_alias=response_model_by_alias,
-                response_model_exclude_unset=bool(
-                    response_model_exclude_unset or response_model_skip_defaults
-                ),
+                response_model_exclude_unset=response_model_exclude_unset,
                 response_model_exclude_defaults=response_model_exclude_defaults,
                 response_model_exclude_none=response_model_exclude_none,
                 include_in_schema=include_in_schema,
@@ -653,9 +629,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -664,8 +639,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -682,9 +655,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -708,9 +679,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -719,8 +689,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -737,9 +705,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -763,9 +729,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -774,8 +739,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -792,9 +755,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -818,9 +779,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -829,8 +789,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -847,9 +805,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -873,9 +829,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -884,8 +839,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -902,9 +855,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -928,9 +879,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -939,8 +889,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -957,9 +905,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -983,9 +929,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -994,8 +939,6 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -1012,9 +955,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
@@ -1038,9 +979,8 @@ class APIRouter(routing.Router):
         deprecated: Optional[bool] = None,
         operation_id: Optional[str] = None,
         response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
-        response_model_exclude: Union[SetIntStr, DictIntStrAny] = set(),
+        response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
         response_model_by_alias: bool = True,
-        response_model_skip_defaults: Optional[bool] = None,
         response_model_exclude_unset: bool = False,
         response_model_exclude_defaults: bool = False,
         response_model_exclude_none: bool = False,
@@ -1049,8 +989,7 @@ class APIRouter(routing.Router):
         name: Optional[str] = None,
         callbacks: Optional[List[APIRoute]] = None,
     ) -> Callable:
-        if response_model_skip_defaults is not None:
-            warning_response_model_skip_defaults_deprecated()  # pragma: nocover
+
         return self.api_route(
             path=path,
             response_model=response_model,
@@ -1067,9 +1006,7 @@ class APIRouter(routing.Router):
             response_model_include=response_model_include,
             response_model_exclude=response_model_exclude,
             response_model_by_alias=response_model_by_alias,
-            response_model_exclude_unset=bool(
-                response_model_exclude_unset or response_model_skip_defaults
-            ),
+            response_model_exclude_unset=response_model_exclude_unset,
             response_model_exclude_defaults=response_model_exclude_defaults,
             response_model_exclude_none=response_model_exclude_none,
             include_in_schema=include_in_schema,
index 08b3e75f5ec844d863487caa95f7ee9a0f32d3ee..d5ace92400aaa0fecbbef3667fc72e7254b23d5e 100644 (file)
@@ -5,49 +5,13 @@ from enum import Enum
 from typing import Any, Dict, Optional, Set, Type, Union, cast
 
 import fastapi
-from fastapi.logger import logger
 from fastapi.openapi.constants import REF_PREFIX
 from pydantic import BaseConfig, BaseModel, create_model
 from pydantic.class_validators import Validator
+from pydantic.fields import FieldInfo, ModelField, UndefinedType
 from pydantic.schema import model_process_schema
 from pydantic.utils import lenient_issubclass
 
-try:
-    from pydantic.fields import FieldInfo, ModelField, UndefinedType
-
-    PYDANTIC_1 = True
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic import Schema as FieldInfo  # type: ignore
-    from pydantic.fields import Field as ModelField  # type: ignore
-
-    class UndefinedType:  # type: ignore
-        def __repr__(self) -> str:
-            return "PydanticUndefined"
-
-    logger.warning(
-        "Pydantic versions < 1.0.0 are deprecated in FastAPI and support will be "
-        "removed soon."
-    )
-    PYDANTIC_1 = False
-
-
-# TODO: remove when removing support for Pydantic < 1.0.0
-def get_field_info(field: ModelField) -> FieldInfo:
-    if PYDANTIC_1:
-        return field.field_info  # type: ignore
-    else:
-        return field.schema  # type: ignore  # pragma: nocover
-
-
-# TODO: remove when removing support for Pydantic < 1.0.0
-def warning_response_model_skip_defaults_deprecated() -> None:
-    logger.warning(  # pragma: nocover
-        "response_model_skip_defaults has been deprecated in favor of "
-        "response_model_exclude_unset to keep in line with Pydantic v1, support for "
-        "it will be removed soon."
-    )
-
 
 def get_model_definitions(
     *,
@@ -98,10 +62,7 @@ def create_response_field(
     )
 
     try:
-        if PYDANTIC_1:
-            return response_field(field_info=field_info)
-        else:  # pragma: nocover
-            return response_field(schema=field_info)
+        return response_field(field_info=field_info)
     except RuntimeError:
         raise fastapi.exceptions.FastAPIError(
             f"Invalid args for response field! Hint: check that {type_} is a valid pydantic field type"
@@ -137,10 +98,7 @@ def create_cloned_field(
     new_field.default = field.default
     new_field.required = field.required
     new_field.model_config = field.model_config
-    if PYDANTIC_1:
-        new_field.field_info = field.field_info
-    else:  # pragma: nocover
-        new_field.schema = field.schema  # type: ignore
+    new_field.field_info = field.field_info
     new_field.allow_none = field.allow_none
     new_field.validate_always = field.validate_always
     if field.sub_fields:
@@ -153,19 +111,11 @@ def create_cloned_field(
             field.key_field, cloned_types=cloned_types
         )
     new_field.validators = field.validators
-    if PYDANTIC_1:
-        new_field.pre_validators = field.pre_validators
-        new_field.post_validators = field.post_validators
-    else:  # pragma: nocover
-        new_field.whole_pre_validators = field.whole_pre_validators  # type: ignore
-        new_field.whole_post_validators = field.whole_post_validators  # type: ignore
+    new_field.pre_validators = field.pre_validators
+    new_field.post_validators = field.post_validators
     new_field.parse_json = field.parse_json
     new_field.shape = field.shape
-    try:
-        new_field.populate_validators()
-    except AttributeError:  # pragma: nocover
-        # TODO: remove when removing support for Pydantic < 1.0.0
-        new_field._populate_validators()  # type: ignore
+    new_field.populate_validators()
     return new_field
 
 
index 2eb8c984291d469155670aea730465411386e21e..516b3e855b740bcb5678c6771d0b6d554f4d5533 100644 (file)
@@ -33,7 +33,7 @@ classifiers = [
 ]
 requires = [
     "starlette ==0.13.6",
-    "pydantic >=0.32.2,<2.0.0"
+    "pydantic >=1.0.0,<2.0.0"
 ]
 description-file = "README.md"
 requires-python = ">=3.6"
index 3205c4cbf07ebab4555c82b6441efbaa9d4fcd98..87b2466e89579d68e24437c5ff932b4c37eebe3b 100644 (file)
@@ -5,13 +5,7 @@ from typing import Optional
 
 import pytest
 from fastapi.encoders import jsonable_encoder
-from pydantic import BaseModel, ValidationError, create_model
-
-try:
-    from pydantic import Field
-except ImportError:  # pragma: nocover
-    # TODO: remove when removing support for Pydantic < 1.0.0
-    from pydantic import Schema as Field
+from pydantic import BaseModel, Field, ValidationError, create_model
 
 
 class Person:
index 458bd70d560f2d97c74a26f482e68bd0c6990eb4..9de4907c247836fd47c56322c83f82d55568117e 100644 (file)
@@ -3,15 +3,6 @@ from fastapi.testclient import TestClient
 
 from docs_src.body_fields.tutorial001 import app
 
-# TODO: remove when removing support for Pydantic < 1.0.0
-try:
-    from pydantic import Field  # noqa
-except ImportError:  # pragma: nocover
-    import pydantic
-
-    pydantic.Field = pydantic.Schema
-
-
 client = TestClient(app)