mirror of https://github.com/tiangolo/fastapi.git
🔊 Add a custom `FastAPIDeprecationWarning` (#14605)
This commit is contained in:
parent
6b53786f62
commit
535b5daa31
|
|
@ -51,7 +51,7 @@ from fastapi.concurrency import (
|
|||
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(
|
||||
|
|
|
|||
|
|
@ -231,3 +231,10 @@ class ResponseValidationError(ValidationException):
|
|||
) -> 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
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from fastapi.dependencies.utils import (
|
|||
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:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||
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 @@ class Param(FieldInfo): # type: ignore[misc]
|
|||
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 @@ class Param(FieldInfo): # type: ignore[misc]
|
|||
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 @@ class Body(FieldInfo): # type: ignore[misc]
|
|||
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 @@ class Body(FieldInfo): # type: ignore[misc]
|
|||
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
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ from fastapi.dependencies.utils import (
|
|||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.exceptions import (
|
||||
EndpointContext,
|
||||
FastAPIDeprecationWarning,
|
||||
FastAPIError,
|
||||
RequestValidationError,
|
||||
ResponseValidationError,
|
||||
|
|
@ -640,7 +641,7 @@ class APIRoute(routing.Route):
|
|||
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 @@ class APIRoute(routing.Route):
|
|||
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(
|
||||
|
|
|
|||
|
|
@ -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 @@ class Param(FieldInfo):
|
|||
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 @@ class Param(FieldInfo):
|
|||
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 @@ class Body(FieldInfo):
|
|||
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 @@ class Body(FieldInfo):
|
|||
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
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from fastapi._compat import (
|
|||
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}"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from typing import Annotated, Any
|
|||
|
||||
import pytest
|
||||
from fastapi import Depends, FastAPI
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
if "--codspeed" not in sys.argv:
|
||||
|
|
@ -89,7 +90,7 @@ def app(basemodel_class: type[Any]) -> FastAPI:
|
|||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
|
||||
category=DeprecationWarning,
|
||||
category=FastAPIDeprecationWarning,
|
||||
)
|
||||
|
||||
@app.post("/sync/validated", response_model=ItemOut)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import warnings
|
|||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
|
||||
from tests.utils import skip_module_if_py_gte_314
|
||||
|
||||
|
|
@ -504,23 +505,23 @@ def test_body_repr():
|
|||
|
||||
# Deprecation warning tests for regex parameter
|
||||
def test_query_regex_deprecation_warning():
|
||||
with pytest.warns(DeprecationWarning, match="`regex` has been deprecated"):
|
||||
with pytest.warns(FastAPIDeprecationWarning, match="`regex` has been deprecated"):
|
||||
Query(regex="^test$")
|
||||
|
||||
|
||||
def test_body_regex_deprecation_warning():
|
||||
with pytest.warns(DeprecationWarning, match="`regex` has been deprecated"):
|
||||
with pytest.warns(FastAPIDeprecationWarning, match="`regex` has been deprecated"):
|
||||
Body(regex="^test$")
|
||||
|
||||
|
||||
# Deprecation warning tests for example parameter
|
||||
def test_query_example_deprecation_warning():
|
||||
with pytest.warns(DeprecationWarning, match="`example` has been deprecated"):
|
||||
with pytest.warns(FastAPIDeprecationWarning, match="`example` has been deprecated"):
|
||||
Query(example="test example")
|
||||
|
||||
|
||||
def test_body_example_deprecation_warning():
|
||||
with pytest.warns(DeprecationWarning, match="`example` has been deprecated"):
|
||||
with pytest.warns(FastAPIDeprecationWarning, match="`example` has been deprecated"):
|
||||
Body(example={"test": "example"})
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import sys
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
|
||||
from tests.utils import skip_module_if_py_gte_314
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ def test_warns_pydantic_v1_model_in_endpoint_param() -> None:
|
|||
app = FastAPI()
|
||||
|
||||
with pytest.warns(
|
||||
DeprecationWarning,
|
||||
FastAPIDeprecationWarning,
|
||||
match=r"pydantic\.v1 is deprecated.*Please update the param data:",
|
||||
):
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ def test_warns_pydantic_v1_model_in_return_type() -> None:
|
|||
app = FastAPI()
|
||||
|
||||
with pytest.warns(
|
||||
DeprecationWarning,
|
||||
FastAPIDeprecationWarning,
|
||||
match=r"pydantic\.v1 is deprecated.*Please update the response model",
|
||||
):
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ def test_warns_pydantic_v1_model_in_response_model() -> None:
|
|||
app = FastAPI()
|
||||
|
||||
with pytest.warns(
|
||||
DeprecationWarning,
|
||||
FastAPIDeprecationWarning,
|
||||
match=r"pydantic\.v1 is deprecated.*Please update the response model",
|
||||
):
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ def test_warns_pydantic_v1_model_in_additional_responses_model() -> None:
|
|||
app = FastAPI()
|
||||
|
||||
with pytest.warns(
|
||||
DeprecationWarning,
|
||||
FastAPIDeprecationWarning,
|
||||
match=r"pydantic\.v1 is deprecated.*In responses=\{\}, please update",
|
||||
):
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Annotated
|
|||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from .utils import needs_py310
|
||||
|
|
@ -10,7 +11,7 @@ from .utils import needs_py310
|
|||
|
||||
def get_client():
|
||||
app = FastAPI()
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.post("/items/")
|
||||
async def read_items(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Annotated
|
|||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from .utils import needs_py310
|
||||
|
|
@ -10,7 +11,7 @@ from .utils import needs_py310
|
|||
|
||||
def get_client():
|
||||
app = FastAPI()
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Union
|
|||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Body, Cookie, FastAPI, Header, Path, Query
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ def create_app():
|
|||
def schema_extra(item: Item):
|
||||
return item
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.post("/example/")
|
||||
def example(item: Item = Body(example={"data": "Data in Body example"})):
|
||||
|
|
@ -38,7 +39,7 @@ def create_app():
|
|||
):
|
||||
return item
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.post("/example_examples/")
|
||||
def example_examples(
|
||||
|
|
@ -83,7 +84,7 @@ def create_app():
|
|||
# ):
|
||||
# return lastname
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/path_example/{item_id}")
|
||||
def path_example(
|
||||
|
|
@ -101,7 +102,7 @@ def create_app():
|
|||
):
|
||||
return item_id
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/path_example_examples/{item_id}")
|
||||
def path_example_examples(
|
||||
|
|
@ -112,7 +113,7 @@ def create_app():
|
|||
):
|
||||
return item_id
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/query_example/")
|
||||
def query_example(
|
||||
|
|
@ -132,7 +133,7 @@ def create_app():
|
|||
):
|
||||
return data
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/query_example_examples/")
|
||||
def query_example_examples(
|
||||
|
|
@ -144,7 +145,7 @@ def create_app():
|
|||
):
|
||||
return data
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/header_example/")
|
||||
def header_example(
|
||||
|
|
@ -167,7 +168,7 @@ def create_app():
|
|||
):
|
||||
return data
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/header_example_examples/")
|
||||
def header_example_examples(
|
||||
|
|
@ -179,7 +180,7 @@ def create_app():
|
|||
):
|
||||
return data
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/cookie_example/")
|
||||
def cookie_example(
|
||||
|
|
@ -199,7 +200,7 @@ def create_app():
|
|||
):
|
||||
return data
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.warns(FastAPIDeprecationWarning):
|
||||
|
||||
@app.get("/cookie_example_examples/")
|
||||
def cookie_example_examples(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import sys
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from tests.utils import skip_module_if_py_gte_314
|
||||
|
|
@ -29,7 +30,7 @@ def get_client(request: pytest.FixtureRequest):
|
|||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
|
||||
category=DeprecationWarning,
|
||||
category=FastAPIDeprecationWarning,
|
||||
)
|
||||
mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import sys
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from tests.utils import skip_module_if_py_gte_314
|
||||
|
|
@ -29,7 +30,7 @@ def get_client(request: pytest.FixtureRequest):
|
|||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
|
||||
category=DeprecationWarning,
|
||||
category=FastAPIDeprecationWarning,
|
||||
)
|
||||
mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import sys
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from tests.utils import skip_module_if_py_gte_314
|
||||
|
|
@ -29,7 +30,7 @@ def get_client(request: pytest.FixtureRequest):
|
|||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
|
||||
category=DeprecationWarning,
|
||||
category=FastAPIDeprecationWarning,
|
||||
)
|
||||
mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from ...utils import needs_py310
|
|||
marks=(
|
||||
needs_py310,
|
||||
pytest.mark.filterwarnings(
|
||||
"ignore:`regex` has been deprecated, please use `pattern` instead:DeprecationWarning"
|
||||
"ignore:`regex` has been deprecated, please use `pattern` instead:fastapi.exceptions.FastAPIDeprecationWarning"
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import importlib
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_pydanticv1
|
||||
|
|
@ -19,7 +20,7 @@ def get_client(request: pytest.FixtureRequest):
|
|||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
|
||||
category=DeprecationWarning,
|
||||
category=FastAPIDeprecationWarning,
|
||||
)
|
||||
mod = importlib.import_module(f"docs_src.request_form_models.{request.param}")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import importlib
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ def get_client(request: pytest.FixtureRequest):
|
|||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
|
||||
category=DeprecationWarning,
|
||||
category=FastAPIDeprecationWarning,
|
||||
)
|
||||
mod = importlib.import_module(f"docs_src.schema_extra_example.{request.param}")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue