โ† oracle_refix

fastapi_14605

resolved RESOLVED UNSUBMITTED PASS ยท None tool calls ยท 0 s ยท fastapi/fastapi

Task input

๐Ÿ”Š Add a custom `FastAPIDeprecationWarning`

๐Ÿ”Š Add a custom `FastAPIDeprecationWarning` and use it for deprecated logic, like Pydantic v1 models.

Motivated by: https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Patch

--- a/fastapi/dependencies/utils.py
+++ b/fastapi/dependencies/utils.py
@@ -51,7 +51,7 @@
     contextmanager_in_threadpool,
 )
 from fastapi.dependencies.models import Dependant
-from fastapi.exceptions import DependencyScopeError
+from fastapi.exceptions import DependencyScopeError, FastAPIDeprecationWarning
 from fastapi.logger import logger
 from fastapi.security.oauth2 import SecurityScopes
 from fastapi.types import DependencyCacheKey
@@ -327,7 +327,7 @@ def get_dependant(
             warnings.warn(
                 "pydantic.v1 is deprecated and will soon stop being supported by FastAPI."
                 f" Please update the param {param_name}: {param_details.type_annotation!r}.",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=5,
             )
         if isinstance(
--- a/fastapi/exceptions.py
+++ b/fastapi/exceptions.py
@@ -231,3 +231,10 @@ def __init__(
     ) -> None:
         super().__init__(errors, endpoint_ctx=endpoint_ctx)
         self.body = body
+
+
+class FastAPIDeprecationWarning(UserWarning):
+    """
+    A custom deprecation warning as DeprecationWarning is ignored
+    Ref: https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries
+    """
--- a/fastapi/openapi/utils.py
+++ b/fastapi/openapi/utils.py
@@ -23,6 +23,7 @@
     get_validation_alias,
 )
 from fastapi.encoders import jsonable_encoder
+from fastapi.exceptions import FastAPIDeprecationWarning
 from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX
 from fastapi.openapi.models import OpenAPI
 from fastapi.params import Body, ParamTypes
@@ -215,9 +216,9 @@ def generate_operation_id(
     *, route: routing.APIRoute, method: str
 ) -> str:  # pragma: nocover
     warnings.warn(
-        "fastapi.openapi.utils.generate_operation_id() was deprecated, "
+        message="fastapi.openapi.utils.generate_operation_id() was deprecated, "
         "it is not used internally, and will be removed soon",
-        DeprecationWarning,
+        category=FastAPIDeprecationWarning,
         stacklevel=2,
     )
     if route.operation_id:
--- a/fastapi/params.py
+++ b/fastapi/params.py
@@ -4,6 +4,7 @@
 from enum import Enum
 from typing import Annotated, Any, Callable, Optional, Union
 
+from fastapi.exceptions import FastAPIDeprecationWarning
 from fastapi.openapi.models import Example
 from pydantic.fields import FieldInfo
 from typing_extensions import Literal, deprecated
@@ -75,7 +76,7 @@ def __init__(
         if example is not _Unset:
             warnings.warn(
                 "`example` has been deprecated, please use `examples` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         self.example = example
@@ -105,7 +106,7 @@ def __init__(
         if regex is not None:
             warnings.warn(
                 "`regex` has been deprecated, please use `pattern` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
@@ -530,7 +531,7 @@ def __init__(
         if example is not _Unset:
             warnings.warn(
                 "`example` has been deprecated, please use `examples` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         self.example = example
@@ -560,7 +561,7 @@ def __init__(
         if regex is not None:
             warnings.warn(
                 "`regex` has been deprecated, please use `pattern` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
--- a/fastapi/routing.py
+++ b/fastapi/routing.py
@@ -47,6 +47,7 @@
 from fastapi.encoders import jsonable_encoder
 from fastapi.exceptions import (
     EndpointContext,
+    FastAPIDeprecationWarning,
     FastAPIError,
     RequestValidationError,
     ResponseValidationError,
@@ -640,7 +641,7 @@ def __init__(
                 warnings.warn(
                     "pydantic.v1 is deprecated and will soon stop being supported by FastAPI."
                     f" Please update the response model {self.response_model!r}.",
-                    category=DeprecationWarning,
+                    category=FastAPIDeprecationWarning,
                     stacklevel=4,
                 )
             self.response_field = create_model_field(
@@ -680,7 +681,7 @@ def __init__(
                     warnings.warn(
                         "pydantic.v1 is deprecated and will soon stop being supported by FastAPI."
                         f" In responses={{}}, please update {model}.",
-                        category=DeprecationWarning,
+                        category=FastAPIDeprecationWarning,
                         stacklevel=4,
                     )
                 response_field = create_model_field(
--- a/fastapi/temp_pydantic_v1_params.py
+++ b/fastapi/temp_pydantic_v1_params.py
@@ -1,6 +1,7 @@
 import warnings
 from typing import Annotated, Any, Callable, Optional, Union
 
+from fastapi.exceptions import FastAPIDeprecationWarning
 from fastapi.openapi.models import Example
 from fastapi.params import ParamTypes
 from typing_extensions import deprecated
@@ -63,7 +64,7 @@ def __init__(
         if example is not _Unset:
             warnings.warn(
                 "`example` has been deprecated, please use `examples` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         self.example = example
@@ -93,7 +94,7 @@ def __init__(
         if regex is not None:
             warnings.warn(
                 "`regex` has been deprecated, please use `pattern` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
@@ -503,7 +504,7 @@ def __init__(
         if example is not _Unset:
             warnings.warn(
                 "`example` has been deprecated, please use `examples` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         self.example = example
@@ -533,7 +534,7 @@ def __init__(
         if regex is not None:
             warnings.warn(
                 "`regex` has been deprecated, please use `pattern` instead",
-                category=DeprecationWarning,
+                category=FastAPIDeprecationWarning,
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
--- a/fastapi/utils.py
+++ b/fastapi/utils.py
@@ -23,6 +23,7 @@
     may_v1,
 )
 from fastapi.datastructures import DefaultPlaceholder, DefaultType
+from fastapi.exceptions import FastAPIDeprecationWarning
 from pydantic import BaseModel
 from pydantic.fields import FieldInfo
 from typing_extensions import Literal
@@ -195,9 +196,9 @@ def generate_operation_id_for_path(
     *, name: str, path: str, method: str
 ) -> str:  # pragma: nocover
     warnings.warn(
-        "fastapi.utils.generate_operation_id_for_path() was deprecated, "
+        message="fastapi.utils.generate_operation_id_for_path() was deprecated, "
         "it is not used internally, and will be removed soon",
-        DeprecationWarning,
+        category=FastAPIDeprecationWarning,
         stacklevel=2,
     )
     operation_id = f"{name}{path}"

Test output

show
........................................................................ [ 72%]
...........................                                              [100%]
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.50.0-py3-none-any/starlette/testclient.py:45
  /Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.50.0-py3-none-any/starlette/testclient.py:45: DeprecationWarning: The anyio.abc.BlockingPortal alias is deprecated, use anyio.from_thread.BlockingPortal instead.
    _PortalFactoryType = Callable[[], AbstractContextManager[anyio.abc.BlockingPortal]]

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
99 passed, 1 skipped, 1 warning in 2.39s