]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🐛 Fix optional sequence handling with new union syntax from Python 3.10 (#14430)
authorVictorien <65306057+Viicos@users.noreply.github.com>
Tue, 2 Dec 2025 16:59:38 +0000 (17:59 +0100)
committerGitHub <noreply@github.com>
Tue, 2 Dec 2025 16:59:38 +0000 (16:59 +0000)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
fastapi/_compat/v2.py
tests/test_compat.py

index 543a42dda0c51e261733c12e7db0634dbf9b01f7..0faa7d5a8d8d600eb01f0e592295cf36730abd69 100644 (file)
@@ -17,7 +17,7 @@ from typing import (
 
 from fastapi._compat import may_v1, shared
 from fastapi.openapi.constants import REF_TEMPLATE
-from fastapi.types import IncEx, ModelNameMap
+from fastapi.types import IncEx, ModelNameMap, UnionType
 from pydantic import BaseModel, TypeAdapter, create_model
 from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
 from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation
@@ -381,7 +381,7 @@ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
 
 def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
     origin_type = get_origin(field.field_info.annotation) or field.field_info.annotation
-    if origin_type is Union:  # Handle optional sequences
+    if origin_type is Union or origin_type is UnionType:  # Handle optional sequences
         union_args = get_args(field.field_info.annotation)
         for union_arg in union_args:
             if union_arg is type(None):
index c3a97209a9cfbdbc1a23861987ad8260c095c21a..26537c5ab71a3a09d19308075d69ff9dfde1d262 100644 (file)
@@ -14,7 +14,7 @@ from fastapi.testclient import TestClient
 from pydantic import BaseModel, ConfigDict
 from pydantic.fields import FieldInfo
 
-from .utils import needs_py_lt_314, needs_pydanticv2
+from .utils import needs_py310, needs_py_lt_314, needs_pydanticv2
 
 
 @needs_pydanticv2
@@ -148,6 +148,19 @@ def test_serialize_sequence_value_with_optional_list():
     assert isinstance(result, list)
 
 
+@needs_pydanticv2
+@needs_py310
+def test_serialize_sequence_value_with_optional_list_pipe_union():
+    """Test that serialize_sequence_value handles optional lists correctly (with new syntax)."""
+    from fastapi._compat import v2
+
+    field_info = FieldInfo(annotation=list[str] | None)
+    field = v2.ModelField(name="items", field_info=field_info)
+    result = v2.serialize_sequence_value(field=field, value=["a", "b", "c"])
+    assert result == ["a", "b", "c"]
+    assert isinstance(result, list)
+
+
 @needs_pydanticv2
 def test_serialize_sequence_value_with_none_first_in_union():
     """Test that serialize_sequence_value handles Union[None, List[...]] correctly."""