]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🐛 Remove `Required` shadowing from fastapi using Pydantic v2 (#12197)
authorJosé Pacheco <pachewise@gmail.com>
Sat, 12 Oct 2024 09:36:32 +0000 (05:36 -0400)
committerGitHub <noreply@github.com>
Sat, 12 Oct 2024 09:36:32 +0000 (11:36 +0200)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
docs_src/query_params_str_validations/tutorial006d.py
docs_src/query_params_str_validations/tutorial006d_an.py
docs_src/query_params_str_validations/tutorial006d_an_py39.py
fastapi/_compat.py
fastapi/dependencies/utils.py

index 42c5bf4ebb57f1652587a9b5ee6efea2063b93e3..a8d69c8899cf041bcd94f93a9eeb81d7de175fec 100644 (file)
@@ -1,11 +1,10 @@
 from fastapi import FastAPI, Query
-from pydantic import Required
 
 app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: str = Query(default=Required, min_length=3)):
+async def read_items(q: str = Query(default=..., min_length=3)):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
index bc8283e1530ca88b95749fbe471f2ca9bc26f07d..ea3b02583a7b68c2fbd029f6bb8ca074c02fdee3 100644 (file)
@@ -1,12 +1,11 @@
 from fastapi import FastAPI, Query
-from pydantic import Required
 from typing_extensions import Annotated
 
 app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Annotated[str, Query(min_length=3)] = Required):
+async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
index 035d9e3bdd3f009ca666884a5480939e3aa26530..687a9f5446e6a2c4bda64877af34a4b39b5d1255 100644 (file)
@@ -1,13 +1,12 @@
 from typing import Annotated
 
 from fastapi import FastAPI, Query
-from pydantic import Required
 
 app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Annotated[str, Query(min_length=3)] = Required):
+async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
index 4b07b44fa582936607b9260ca19f99c6a350cadc..56c5d744e40baf69e2cc240714d96d11c20af3e0 100644 (file)
@@ -71,7 +71,7 @@ if PYDANTIC_V2:
             general_plain_validator_function as with_info_plain_validator_function,  # noqa: F401
         )
 
-    Required = PydanticUndefined
+    RequiredParam = PydanticUndefined
     Undefined = PydanticUndefined
     UndefinedType = PydanticUndefinedType
     evaluate_forwardref = eval_type_lenient
@@ -313,9 +313,10 @@ else:
     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]
-        Required as Required,  # noqa: F401
-    )
+
+    # Keeping old "Required" functionality from Pydantic V1, without
+    # shadowing typing.Required.
+    RequiredParam: Any = Ellipsis  # type: ignore[no-redef]
     from pydantic.fields import (  # type: ignore[no-redef,attr-defined]
         Undefined as Undefined,
     )
index 813c74620d725790d07989aa125c7d3f53e57a47..87653c80df9789927cee546cd84064db0c8e889a 100644 (file)
@@ -24,7 +24,7 @@ from fastapi._compat import (
     PYDANTIC_V2,
     ErrorWrapper,
     ModelField,
-    Required,
+    RequiredParam,
     Undefined,
     _regenerate_error_with_loc,
     copy_field_info,
@@ -377,7 +377,9 @@ def analyze_param(
             field_info = copy_field_info(
                 field_info=fastapi_annotation, annotation=use_annotation
             )
-            assert field_info.default is Undefined or field_info.default is Required, (
+            assert (
+                field_info.default is Undefined or field_info.default is RequiredParam
+            ), (
                 f"`{field_info.__class__.__name__}` default value cannot be set in"
                 f" `Annotated` for {param_name!r}. Set the default value with `=` instead."
             )
@@ -385,7 +387,7 @@ def analyze_param(
                 assert not is_path_param, "Path parameters cannot have default values"
                 field_info.default = value
             else:
-                field_info.default = Required
+                field_info.default = RequiredParam
         # Get Annotated Depends
         elif isinstance(fastapi_annotation, params.Depends):
             depends = fastapi_annotation
@@ -434,9 +436,9 @@ def analyze_param(
         ), f"Cannot specify FastAPI annotation for type {type_annotation!r}"
     # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
     elif field_info is None and depends is None:
-        default_value = value if value is not inspect.Signature.empty else Required
+        default_value = value if value is not inspect.Signature.empty else RequiredParam
         if is_path_param:
-            # We might check here that `default_value is Required`, but the fact is that the same
+            # We might check here that `default_value is RequiredParam`, but the fact is that the same
             # parameter might sometimes be a path parameter and sometimes not. See
             # `tests/test_infer_param_optionality.py` for an example.
             field_info = params.Path(annotation=use_annotation)
@@ -480,7 +482,7 @@ def analyze_param(
             type_=use_annotation_from_field_info,
             default=field_info.default,
             alias=alias,
-            required=field_info.default in (Required, Undefined),
+            required=field_info.default in (RequiredParam, Undefined),
             field_info=field_info,
         )
         if is_path_param: