Browse Source

Merge branch 'master' into gh5065--use-wrapped-attribute

pull/5077/head
Sebastián Ramírez 8 months ago
committed by GitHub
parent
commit
9c001863f3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      docs/en/docs/release-notes.md
  2. 4
      fastapi/_compat/v2.py
  3. 15
      tests/test_compat.py

4
docs/en/docs/release-notes.md

@ -11,6 +11,10 @@ hide:
* ✨ Handle wrapped dependencies. PR [#9555](https://github.com/fastapi/fastapi/pull/9555) by [@phy1729](https://github.com/phy1729). * ✨ Handle wrapped dependencies. PR [#9555](https://github.com/fastapi/fastapi/pull/9555) by [@phy1729](https://github.com/phy1729).
### Fixes
* 🐛 Fix optional sequence handling with new union syntax from Python 3.10. PR [#14430](https://github.com/fastapi/fastapi/pull/14430) by [@Viicos](https://github.com/Viicos).
### Refactors ### Refactors
* 🔥 Remove dangling extra condiitonal no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo). * 🔥 Remove dangling extra condiitonal no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo).

4
fastapi/_compat/v2.py

@ -17,7 +17,7 @@ from typing import (
from fastapi._compat import may_v1, shared from fastapi._compat import may_v1, shared
from fastapi.openapi.constants import REF_TEMPLATE 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 BaseModel, TypeAdapter, create_model
from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation 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]: def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
origin_type = get_origin(field.field_info.annotation) or field.field_info.annotation 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) union_args = get_args(field.field_info.annotation)
for union_arg in union_args: for union_arg in union_args:
if union_arg is type(None): if union_arg is type(None):

15
tests/test_compat.py

@ -14,7 +14,7 @@ from fastapi.testclient import TestClient
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from pydantic.fields import FieldInfo 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 @needs_pydanticv2
@ -148,6 +148,19 @@ def test_serialize_sequence_value_with_optional_list():
assert isinstance(result, 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 @needs_pydanticv2
def test_serialize_sequence_value_with_none_first_in_union(): def test_serialize_sequence_value_with_none_first_in_union():
"""Test that serialize_sequence_value handles Union[None, List[...]] correctly.""" """Test that serialize_sequence_value handles Union[None, List[...]] correctly."""

Loading…
Cancel
Save