โ† oracle_full

fastapi_14512

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

Task input

๐Ÿ› Fix support for tagged union with discriminator inside of `Annotated` with `Body()`

๐Ÿ› Fix support for tagged union with discriminator inside of `Annotated` with `Body()`

Related to: https://github.com/fastapi/fastapi/discussions/14495, https://github.com/fastapi/fastapi/issues/14508

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Patch

--- a/fastapi/_compat/v2.py
+++ b/fastapi/_compat/v2.py
@@ -18,7 +18,7 @@
 from fastapi._compat import may_v1, shared
 from fastapi.openapi.constants import REF_TEMPLATE
 from fastapi.types import IncEx, ModelNameMap, UnionType
-from pydantic import BaseModel, ConfigDict, TypeAdapter, create_model
+from pydantic import BaseModel, ConfigDict, Field, TypeAdapter, create_model
 from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
 from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation
 from pydantic import ValidationError as ValidationError
@@ -50,6 +50,45 @@
 evaluate_forwardref = eval_type_lenient
 Validator = Any
 
+# TODO: remove when dropping support for Pydantic < v2.12.3
+_Attrs = {
+    "default": ...,
+    "default_factory": None,
+    "alias": None,
+    "alias_priority": None,
+    "validation_alias": None,
+    "serialization_alias": None,
+    "title": None,
+    "field_title_generator": None,
+    "description": None,
+    "examples": None,
+    "exclude": None,
+    "exclude_if": None,
+    "discriminator": None,
+    "deprecated": None,
+    "json_schema_extra": None,
+    "frozen": None,
+    "validate_default": None,
+    "repr": True,
+    "init": None,
+    "init_var": None,
+    "kw_only": None,
+}
+
+
+# TODO: remove when dropping support for Pydantic < v2.12.3
+def asdict(field_info: FieldInfo) -> Dict[str, Any]:
+    attributes = {}
+    for attr in _Attrs:
+        value = getattr(field_info, attr, Undefined)
+        if value is not Undefined:
+            attributes[attr] = value
+    return {
+        "annotation": field_info.annotation,
+        "metadata": field_info.metadata,
+        "attributes": attributes,
+    }
+
 
 class BaseConfig:
     pass
@@ -95,10 +134,15 @@ def __post_init__(self) -> None:
                 warnings.simplefilter(
                     "ignore", category=UnsupportedFieldAttributeWarning
                 )
+            # TODO: remove after dropping support for Python 3.8 and
+            # setting the min Pydantic to v2.12.3 that adds asdict()
+            field_dict = asdict(self.field_info)
             annotated_args = (
-                self.field_info.annotation,
-                *self.field_info.metadata,
-                self.field_info,
+                field_dict["annotation"],
+                *field_dict["metadata"],
+                # this FieldInfo needs to be created again so that it doesn't include
+                # the old field info metadata and only the rest of the attributes
+                Field(**field_dict["attributes"]),
             )
             self._type_adapter: TypeAdapter[Any] = TypeAdapter(
                 Annotated[annotated_args],

Test output

show
...                                                                      [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
3 passed, 1 warning in 0.45s