resolved RESOLVED PASS · 44 tool calls · 290 s · fastapi/fastapi
🐛 Fix optional sequence handling with new union syntax from Python 3.10 https://github.com/fastapi/fastapi/pull/14297 is only taking one union type into account. I can only recommend using https://github.com/pydantic/typing-inspection for these kind of checks (see https://typing-inspection.pydantic.dev/latest/usage/ for motivation).
| # | Tool | Arguments | Result |
|---|---|---|---|
| 1 | run_command | {
"command": "grep -rn \"Union\" --include=*.py fastapi | grep \"Optional\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/utils.py:56full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/utils.py:569: body: Optional[Union[Dict[str, Any], FormData]] = None,\nfastapi/dependencies/utils.py:924: received_body: Optional[Union[Dict[str, Any], FormData]],\nfastapi/applications.py:293: Optional[List[Dict[str, Union[str, Any]]]],\nfastapi/applications.py:570: Optional[Dict[str, Union[str, Any]]],\nfastapi/applications.py:603: Optional[Dict[str, Union[str, Any]]],\nfastapi/applications.py:692: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:1148: tags: Optional[List[Union[str, Enum]]] = None,\nfastapi/applications.py:1153: responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,\nfastapi/applications.py:1206: tags: Optional[List[Union[str, Enum]]] = None,\nfastapi/applications.py:1211: responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,\nfastapi/applications.py:1346: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:1388: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:1606: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:1672: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:1979: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:2045: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:2357: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:2423: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:2735: Optional[List[Union[str, Enum]]],\n", "stderr": "", "exit_code": 0} |
| 2 | run_command | {
"command": "grep -rn \"Union\" --include=*.py fastapi | grep \"get_type_hints\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 3 | run_command | {
"command": "grep -rn \"Union\" --include=*.py fastapi | grep \"get_args\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 4 | run_command | {
"command": "grep -rn \"Union\" --include=*.py fastapi | grep \"get_origin\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 5 | run_command | {
"command": "grep -rn \"Union\" --include=*.py fastapi | grep \"typing\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/utils.py:83full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/exceptions.py:1:from typing import Any, Dict, Optional, Sequence, Type, Union\nfastapi/temp_pydantic_v1_params.py:2:from typing import Any, Callable, Dict, List, Optional, Union\nfastapi/security/api_key.py:1:from typing import Optional, Union\nfastapi/security/oauth2.py:1:from typing import Any, Dict, List, Optional, Union, cast\nfastapi/encoders.py:17:from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union\nfastapi/types.py:3:from typing import Any, Callable, Dict, Optional, Set, Tuple, Type, TypeVar, Union\nfastapi/param_functions.py:1:from typing import Any, Callable, Dict, List, Optional, Sequence, Union\nfastapi/params.py:4:from typing import Any, Callable, Dict, List, Optional, Sequence, Union\nfastapi/openapi/models.py:2:from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union\nfastapi/openapi/utils.py:4:from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast\n", "stderr": "", "exit_code": 0} |
| 6 | run_command | {
"command": "sed -n '830,860p' fastapi/dependencies/utils.py"
} | {"status": "ok", "stdout": "\n\ndef is_union_of_base_models(field_type: Any) -> bool:\n \"\"\"Check if field type is a Union where all members are BaseModel subfull{"status": "ok", "stdout": "\n\ndef is_union_of_base_models(field_type: Any) -> bool:\n \"\"\"Check if field type is a Union where all members are BaseModel subclasses.\"\"\"\n from fastapi.types import UnionType\n\n origin = get_origin(field_type)\n\n # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\n if origin is not Union and origin is not UnionType:\n return False\n\n union_args = get_args(field_type)\n\n for arg in union_args:\n if not _is_model_class(arg):\n return False\n\n return True\n\n\ndef _should_embed_body_fields(fields: List[ModelField]) -> bool:\n if not fields:\n return False\n # More than one dependency could have the same field, it would show up as multiple\n # fields but it's the same one, so count them by name\n body_param_names_set = {field.name for field in fields}\n # A top level field has to be a single field, not multiple\n if len(body_param_names_set) > 1:\n return True\n first_field = fields[0]\n", "stderr": "", "exit_code": 0} |
| 7 | run_command | {
"command": "grep -rn \"UnionType\" fastapi | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union tfull{"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\nfastapi/_compat/shared.py:20:from fastapi.types import UnionType\nfastapi/_compat/shared.py:39: types.UnionType,\nfastapi/_compat/shared.py:85: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:111: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:132: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:151: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:162: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:171: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:186: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:203: if origin is Union or origin is UnionType:\nfastapi/types.py:8:UnionType = getattr(types, \"UnionType\", Union)\n", "stderr": "", "exit_code": 0} |
| 8 | run_command | {
"command": "sed -n '10,100p' fastapi/_compat/shared.py"
} | {"status": "ok", "stdout": " List,\n Mapping,\n Sequence,\n Set,\n Tuple,\n Type,\n Union,\n)\n\nfrom fastapi._compat import may_v1\nfrom fastapi.types import Ufull{"status": "ok", "stdout": " List,\n Mapping,\n Sequence,\n Set,\n Tuple,\n Type,\n Union,\n)\n\nfrom fastapi._compat import may_v1\nfrom fastapi.types import UnionType\nfrom pydantic import BaseModel\nfrom pydantic.version import VERSION as PYDANTIC_VERSION\nfrom starlette.datastructures import UploadFile\nfrom typing_extensions import Annotated, get_args, get_origin\n\n# Copy from Pydantic v2, compatible with v1\nif sys.version_info < (3, 9):\n # Pydantic no longer supports Python 3.8, this might be incorrect, but the code\n # this is used for is also never reached in this codebase, as it's a copy of\n # Pydantic's lenient_issubclass, just for compatibility with v1\n # TODO: remove when dropping support for Python 3.8\n WithArgsTypes: Tuple[Any, ...] = ()\nelif sys.version_info < (3, 10):\n WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # type: ignore[attr-defined]\nelse:\n WithArgsTypes: tuple[Any, ...] = (\n typing._GenericAlias, # type: ignore[attr-defined]\n types.GenericAlias,\n types.UnionType,\n ) # pyright: ignore[reportAttributeAccessIssue]\n\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2\n\n\nsequence_annotation_to_type = {\n Sequence: list,\n List: list,\n list: list,\n Tuple: tuple,\n tuple: tuple,\n Set: set,\n set: set,\n FrozenSet: frozenset,\n frozenset: frozenset,\n Deque: deque,\n deque: deque,\n}\n\nsequence_types = tuple(sequence_annotation_to_type.keys())\n\nUrl: Type[Any]\n\n\n# Copy of Pydantic v2, compatible with v1\ndef lenient_issubclass(\n cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...], None]\n) -> bool:\n try:\n return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type]\n except TypeError: # pragma: no cover\n if isinstance(cls, WithArgsTypes) |
| 9 | run_command | {
"command": "sed -n '60,80p' fastapi/_compat/shared.py"
} | {"status": "ok", "stdout": "sequence_types = tuple(sequence_annotation_to_type.keys())\n\nUrl: Type[Any]\n\n\n# Copy of Pydantic v2, compatible with v1\ndef lenfull{"status": "ok", "stdout": "sequence_types = tuple(sequence_annotation_to_type.keys())\n\nUrl: Type[Any]\n\n\n# Copy of Pydantic v2, compatible with v1\ndef lenient_issubclass(\n cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...], None]\n) -> bool:\n try:\n return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type]\n except TypeError: # pragma: no cover\n if isinstance(cls, WithArgsTypes):\n return False\n raise # pragma: no cover\n\n\ndef _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:\n if lenient_issubclass(annotation, (str, bytes)):\n return False\n return lenient_issubclass(annotation, sequence_types) # type: ignore[arg-type]\n", "stderr": "", "exit_code": 0} |
| 10 | run_command | {
"command": "sed -n '80,95p' fastapi/_compat/shared.py"
} | {"status": "ok", "stdout": " return lenient_issubclass(annotation, sequence_types) # type: ignore[arg-type]\n\n\ndef field_annotation_is_sequence(annotation: Unfull{"status": "ok", "stdout": " return lenient_issubclass(annotation, sequence_types) # type: ignore[arg-type]\n\n\ndef field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:\n origin = get_origin(annotation)\n if origin is Union or origin is UnionType:\n for arg in get_args(annotation):\n if field_annotation_is_sequence(arg):\n return True\n return False\n return _annotation_is_sequence(annotation) or _annotation_is_sequence(\n get_origin(annotation)\n )\n\n\ndef value_is_sequence(value: Any) -> bool:\n", "stderr": "", "exit_code": 0} |
| 11 | write_file | {
"content": "\nfrom typing import Union, List, Optional, Sequence\nfrom fastapi._compat.shared import field_annotation_is_sequence\nimport types\n\ndef test_field_annotation_is_sequence_py310_union():\n # Test with typing.Union\n assert field_annotation_is_sequence(Union[List[int], None]) is True\n assert field_annotation_is_sequence(Union[int, None]) is False\n \n # Test with Python 3.10 | syntax (types.UnionType)\n # We use eval to avoid SyntaxError on older Python versions if this is run there,\n # but the environment is Python 3.10+\n try:\n # list[int] | None\n assert field_annotation_is_sequence(eval(\"list[int] | None\")) is True\n # int | None\n assert field_annotation_is_sequence(eval(\"int | None\")) is False\n # list[int] | int\n assert field_annotation_is_sequence(eval(\"list[int] | int\")) is True\n except SyntaxError:\n print(\"Python version does not support | operator\")\n\ndef test_field_annotation_is_sequence_nested_union():\n # Union[Union[List[int], None], None]\n assert field_annotation_is_sequence(Union[Union[List[int], None], None]) is True\n \n try:\n # (list[int] | None) | None\n assert field_annotation_is_sequence(eval(\"(list[int] | None) | None\")) is True\n except SyntaxError:\n pass\n\nif __name__ == \"__main__\":\n try:\n test_field_annotation_is_sequence_py310_union()\n test_field_annotation_is_sequence_nested_union()\n print(\"All tests passed!\")\n except AssertionError as e:\n print(f\"Test failed: {e}\")\n except Exception as e:\n print(f\"An error occurred: {e}\")\n",
"filepath": "/tmp/test_union_sequence.py"
} | {"status": "error", "error_type": "FileWriteError", "error_message": "Path traversal detected: '/tmp/test_union_sequence.py' escapes workspace root."}full{"status": "error", "error_type": "FileWriteError", "error_message": "Path traversal detected: '/tmp/test_union_sequence.py' escapes workspace root."} |
| 12 | write_file | {
"content": "\nfrom typing import Union, List, Optional, Sequence\nfrom fastapi._compat.shared import field_annotation_is_sequence\nimport types\n\ndef test_field_annotation_is_sequence_py310_union():\n # Test with typing.Union\n assert field_annotation_is_sequence(Union[List[int], None]) is True\n assert field_annotation_is_sequence(Union[int, None]) is False\n \n # Test with Python 3.10 | syntax (types.UnionType)\n try:\n # list[int] | None\n assert field_annotation_is_sequence(eval(\"list[int] | None\")) is True\n # int | None\n assert field_annotation_is_sequence(eval(\"int | None\")) is False\n # list[int] | int\n assert field_annotation_is_sequence(eval(\"list[int] | int\")) is True\n except SyntaxError:\n print(\"Python version does not support | operator\")\n\ndef test_field_annotation_is_sequence_nested_union():\n # Union[Union[List[int], None], None]\n assert field_annotation_is_sequence(Union[Union[List[int], None], None]) is True\n \n try:\n # (list[int] | None) | None\n assert field_annotation_is_sequence(eval(\"(list[int] | None) | None\")) is True\n except SyntaxError:\n pass\n\nif __name__ == \"__main__\":\n try:\n test_field_annotation_is_sequence_py310_union()\n test_field_annotation_is_sequence_nested_union()\n print(\"All tests passed!\")\n except AssertionError as e:\n print(f\"Test failed: {e}\")\n except Exception as e:\n print(f\"An error occurred: {e}\")\n",
"filepath": "test_union_sequence.py"
} | {"status": "ok", "filepath": "test_union_sequence.py", "size": 1482}full{"status": "ok", "filepath": "test_union_sequence.py", "size": 1482} |
| 13 | run_command | {
"command": "python test_union_sequence.py"
} | {"status": "ok", "stdout": "All tests passed!\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "All tests passed!\n", "stderr": "", "exit_code": 0} |
| 14 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"Optional\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/utils.py:56full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/utils.py:569: body: Optional[Union[Dict[str, Any], FormData]] = None,\nfastapi/dependencies/utils.py:924: received_body: Optional[Union[Dict[str, Any], FormData]],\nfastapi/applications.py:293: Optional[List[Dict[str, Union[str, Any]]]],\nfastapi/applications.py:570: Optional[Dict[str, Union[str, Any]]],\nfastapi/applications.py:603: Optional[Dict[str, Union[str, Any]]],\nfastapi/applications.py:692: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:1148: tags: Optional[List[Union[str, Enum]]] = None,\nfastapi/applications.py:1153: responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,\nfastapi/applications.py:1206: tags: Optional[List[Union[str, Enum]]] = None,\nfastapi/applications.py:1211: responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,\nfastapi/applications.py:1346: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:1388: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:1606: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:1672: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:1979: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:2045: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:2357: Optional[List[Union[str, Enum]]],\nfastapi/applications.py:2423: Optional[Dict[Union[int, str], Dict[str, Any]]],\nfastapi/applications.py:2735: Optional[List[Union[str, Enum]]],\n", "stderr": "", "exit_code": 0} |
| 15 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"get_origin\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 16 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"get_args\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 17 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"UnionType\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union tfull{"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\nfastapi/_compat/shared.py:20:from fastapi.types import UnionType\nfastapi/_compat/shared.py:39: types.UnionType,\nfastapi/_compat/shared.py:85: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:111: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:132: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:151: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:162: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:171: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:186: if origin is Union or origin is UnionType:\nfastapi/_compat/shared.py:203: if origin is Union or origin is UnionType:\nfastapi/types.py:8:UnionType = getattr(types, \"UnionType\", Union)\n", "stderr": "", "exit_code": 0} |
| 18 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"Union\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:4full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:45: scope: Union[Literal[\"function\", \"request\"], None] = None\nfastapi/dependencies/models.py:108: def computed_scope(self) -> Union[str, None]:\nfastapi/dependencies/utils.py:18: Union,\nfastapi/dependencies/utils.py:237: scope: Union[Literal[\"function\", \"request\"], None] = None,\nfastapi/dependencies/utils.py:380: fastapi_annotation: Union[\nfastapi/dependencies/utils.py:567: request: Union[Request, WebSocket],\nfastapi/dependencies/utils.py:569: body: Optional[Union[Dict[str, Any], FormData]] = None,\nfastapi/dependencies/utils.py:724: field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None\nfastapi/dependencies/utils.py:749: received_params: Union[Mapping[str, Any], QueryParams, Headers],\nfastapi/dependencies/utils.py:833: \"\"\"Check if field type is a Union where all members are BaseModel subclasses.\"\"\"\nfastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\nfastapi/dependencies/utils.py:897: results: List[Union[bytes, str]] = []\nfastapi/dependencies/utils.py:924: received_body: Optional[Union[Dict[str, Any], FormData]],\nfastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/_compat/may_v1.py:116: *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]\nfastapi/_compat/shared.py:16: Union,\nfastapi/_compat/shared.py:20:from fastapi.types import UnionType\n", "stderr": "", "exit_code": 0} |
| 19 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"UnionType\" | grep -v \"_compat/shared.py\" | grep -v \"types.py\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union tfull{"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\n", "stderr": "", "exit_code": 0} |
| 20 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"Union\" | grep -v \"UnionType\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:4full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:45: scope: Union[Literal[\"function\", \"request\"], None] = None\nfastapi/dependencies/models.py:108: def computed_scope(self) -> Union[str, None]:\nfastapi/dependencies/utils.py:18: Union,\nfastapi/dependencies/utils.py:237: scope: Union[Literal[\"function\", \"request\"], None] = None,\nfastapi/dependencies/utils.py:380: fastapi_annotation: Union[\nfastapi/dependencies/utils.py:567: request: Union[Request, WebSocket],\nfastapi/dependencies/utils.py:569: body: Optional[Union[Dict[str, Any], FormData]] = None,\nfastapi/dependencies/utils.py:724: field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None\nfastapi/dependencies/utils.py:749: received_params: Union[Mapping[str, Any], QueryParams, Headers],\nfastapi/dependencies/utils.py:833: \"\"\"Check if field type is a Union where all members are BaseModel subclasses.\"\"\"\nfastapi/dependencies/utils.py:897: results: List[Union[bytes, str]] = []\nfastapi/dependencies/utils.py:924: received_body: Optional[Union[Dict[str, Any], FormData]],\nfastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/_compat/may_v1.py:116: *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]\nfastapi/_compat/shared.py:16: Union,\nfastapi/_compat/shared.py:67: cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...], None]\nfastapi/_compat/shared.py:77:def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:\nfastapi/_compat/shared.py:83:def field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:\nfastapi/_compat/shared.py:99:def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:\n", "stderr": "", "exit_code": 0} |
| 21 | run_command | {
"command": "cd /workspace && git status --short && git diff --stat"
} | {"status": "ok", "stdout": "?? test_union_sequence.py\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "?? test_union_sequence.py\n", "stderr": "", "exit_code": 0} |
| 22 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"get_origin\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 23 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"get_args\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 24 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"UnionType\" | grep -v \"_compat/shared.py\" | grep -v \"types.py\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union tfull{"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\n", "stderr": "", "exit_code": 0} |
| 25 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"Union\" | head -40"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:4full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:45: scope: Union[Literal[\"function\", \"request\"], None] = None\nfastapi/dependencies/models.py:108: def computed_scope(self) -> Union[str, None]:\nfastapi/dependencies/utils.py:18: Union,\nfastapi/dependencies/utils.py:237: scope: Union[Literal[\"function\", \"request\"], None] = None,\nfastapi/dependencies/utils.py:380: fastapi_annotation: Union[\nfastapi/dependencies/utils.py:567: request: Union[Request, WebSocket],\nfastapi/dependencies/utils.py:569: body: Optional[Union[Dict[str, Any], FormData]] = None,\nfastapi/dependencies/utils.py:724: field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None\nfastapi/dependencies/utils.py:749: received_params: Union[Mapping[str, Any], QueryParams, Headers],\nfastapi/dependencies/utils.py:833: \"\"\"Check if field type is a Union where all members are BaseModel subclasses.\"\"\"\nfastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\nfastapi/dependencies/utils.py:897: results: List[Union[bytes, str]] = []\nfastapi/dependencies/utils.py:924: received_body: Optional[Union[Dict[str, Any], FormData]],\nfastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/_compat/may_v1.py:116: *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]\nfastapi/_compat/shared.py:16: Union,\nfastapi/_compat/shared.py:20:from fastapi.types import UnionType\nfastapi/_compat/shared.py:39: types.UnionType,\nfastapi/_compat/shared.py:67: cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...], None |
| 26 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"get_origin\" | grep -v \"_compat/shared.py\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 27 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"get_args\" | grep -v \"_compat/shared.py\" | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 28 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"UnionType\" | grep -v \"_compat/shared.py\" | grep -v \"types.py\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union tfull{"status": "ok", "stdout": "fastapi/dependencies/utils.py:834: from fastapi.types import UnionType\nfastapi/dependencies/utils.py:838: # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\nfastapi/dependencies/utils.py:839: if origin is not Union and origin is not UnionType:\n", "stderr": "", "exit_code": 0} |
| 29 | run_command | {
"command": "sed -n '830,850p' fastapi/dependencies/utils.py"
} | {"status": "ok", "stdout": "\n\ndef is_union_of_base_models(field_type: Any) -> bool:\n \"\"\"Check if field type is a Union where all members are BaseModel subfull{"status": "ok", "stdout": "\n\ndef is_union_of_base_models(field_type: Any) -> bool:\n \"\"\"Check if field type is a Union where all members are BaseModel subclasses.\"\"\"\n from fastapi.types import UnionType\n\n origin = get_origin(field_type)\n\n # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)\n if origin is not Union and origin is not UnionType:\n return False\n\n union_args = get_args(field_type)\n\n for arg in union_args:\n if not _is_model_class(arg):\n return False\n\n return True\n\n\n", "stderr": "", "exit_code": 0} |
| 30 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"Union\" | grep -v \"_compat/shared.py\" | grep -v \"types.py\" | grep -v \"dependencies/utils.py\" | head -20"
} | {"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:4full{"status": "ok", "stdout": "fastapi/dependencies/models.py:5:from typing import Any, Callable, List, Optional, Sequence, Union\nfastapi/dependencies/models.py:45: scope: Union[Literal[\"function\", \"request\"], None] = None\nfastapi/dependencies/models.py:108: def computed_scope(self) -> Union[str, None]:\nfastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/_compat/may_v1.py:116: *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]\nfastapi/_compat/v1.py:13: Union,\nfastapi/_compat/v1.py:163: ref: Union[str, None] = None,\nfastapi/_compat/v1.py:172: flat_models: Set[Union[Type[BaseModel], Type[Enum]]],\nfastapi/_compat/v1.py:173: model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],\nfastapi/_compat/model_field.py:6: Union,\nfastapi/_compat/model_field.py:39: loc: Tuple[Union[int, str], ...] = (),\nfastapi/_compat/model_field.py:40: ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]: ...\nfastapi/_compat/model_field.py:47: include: Union[IncEx, None] = None,\nfastapi/_compat/model_field.py:48: exclude: Union[IncEx, None] = None,\nfastapi/_compat/v2.py:14: Union,\nfastapi/_compat/v2.py:111: loc: Tuple[Union[int, str], ...] = (),\nfastapi/_compat/v2.py:112: ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:\nfastapi/_compat/v2.py:128: include: Union[IncEx, None] = None,\nfastapi/_compat/v2.py:129: exclude: Union[IncEx, None] = None,\nfastapi/_compat/v2.py:186: override_mode: Union[Literal[\"validation\"], None] = (\n", "stderr": "", "exit_code": 0} |
| 31 | run_command | {
"command": "grep -rn \"Union\" fastapi | grep \"Union\" | grep -v \"_compat/shared.py\" | grep -v \"types.py\" | grep -v \"dependencies/utils.py\" | grep -v \"dependencies/models.py\" | head -20"
} | {"status": "ok", "stdout": "fastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/_compat/may_v1.py:116full{"status": "ok", "stdout": "fastapi/_compat/may_v1.py:2:from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union\nfastapi/_compat/may_v1.py:116: *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]\nfastapi/_compat/v1.py:13: Union,\nfastapi/_compat/v1.py:163: ref: Union[str, None] = None,\nfastapi/_compat/v1.py:172: flat_models: Set[Union[Type[BaseModel], Type[Enum]]],\nfastapi/_compat/v1.py:173: model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],\nfastapi/_compat/model_field.py:6: Union,\nfastapi/_compat/model_field.py:39: loc: Tuple[Union[int, str], ...] = (),\nfastapi/_compat/model_field.py:40: ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]: ...\nfastapi/_compat/model_field.py:47: include: Union[IncEx, None] = None,\nfastapi/_compat/model_field.py:48: exclude: Union[IncEx, None] = None,\nfastapi/_compat/v2.py:14: Union,\nfastapi/_compat/v2.py:111: loc: Tuple[Union[int, str], ...] = (),\nfastapi/_compat/v2.py:112: ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:\nfastapi/_compat/v2.py:128: include: Union[IncEx, None] = None,\nfastapi/_compat/v2.py:129: exclude: Union[IncEx, None] = None,\nfastapi/_compat/v2.py:186: override_mode: Union[Literal[\"validation\"], None] = (\nfastapi/_compat/v2.py:217: override_mode: Union[Literal[\"validation\"], None] = (\nfastapi/_compat/v2.py:384: if origin_type is Union: # Handle optional sequences\nfastapi/_compat/v2.py:421:TypeModelOrEnum = Union[Type[\"BaseModel\"], Type[Enum]]\n", "stderr": "", "exit_code": 0} |
| 32 | run_command | {
"command": "sed:run_command{command:"
} | {"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: line 1: sed:run_command{command:: command not found\n", "details": {"stdout": "",full{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: line 1: sed:run_command{command:: command not found\n", "details": {"stdout": "", "stderr": "/bin/bash: line 1: sed:run_command{command:: command not found\n", "exit_code": 127}} |
| 33 | run_command | {
"command": "sed -n '380,400p' fastapi/_compat/v2.py"
} | {"status": "ok", "stdout": "\n\ndef serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:\n origin_type = get_origin(field.field_info.annfull{"status": "ok", "stdout": "\n\ndef serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:\n origin_type = get_origin(field.field_info.annotation) or field.field_info.annotation\n if origin_type is Union: # Handle optional sequences\n union_args = get_args(field.field_info.annotation)\n for union_arg in union_args:\n if union_arg is type(None):\n continue\n origin_type = get_origin(union_arg) or union_arg\n break\n assert issubclass(origin_type, shared.sequence_types) # type: ignore[arg-type]\n return shared.sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return]\n\n\ndef get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:\n error = ValidationError.from_exception_data(\n \"Field required\", [{\"type\": \"missing\", \"loc\": loc, \"input\": {}}]\n ).errors(include_url=False)[0]\n error[\"input\"] = None\n return error # type: ignore[return-value]\n", "stderr": "", "exit_code": 0} |
| 34 | run_command | {
"command": "sed -n '1,30p' fastapi/_compat/v2.py"
} | {"status": "ok", "stdout": "import re\nimport warnings\nfrom copy import copy, deepcopy\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom typing ifull{"status": "ok", "stdout": "import re\nimport warnings\nfrom copy import copy, deepcopy\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom typing import (\n Any,\n Dict,\n List,\n Sequence,\n Set,\n Tuple,\n Type,\n Union,\n cast,\n)\n\nfrom fastapi._compat import may_v1, shared\nfrom fastapi.openapi.constants import REF_TEMPLATE\nfrom fastapi.types import IncEx, ModelNameMap\nfrom pydantic import BaseModel, TypeAdapter, create_model\nfrom pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError\nfrom pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation\nfrom pydantic import ValidationError as ValidationError\nfrom pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined]\n GetJsonSchemaHandler as GetJsonSchemaHandler,\n)\nfrom pydantic._internal._typing_extra import eval_type_lenient\nfrom pydantic._internal._utils import lenient_issubclass as lenient_issubclass\nfrom pydantic.fields import FieldInfo as FieldInfo\n", "stderr": "", "exit_code": 0} |
| 35 | run_command | {
"command": "sed -n '20,40p' fastapi/_compat/v2.py"
} | {"status": "ok", "stdout": "from fastapi.types import IncEx, ModelNameMap\nfrom pydantic import BaseModel, TypeAdapter, create_model\nfrom pydantic import Pydanfull{"status": "ok", "stdout": "from fastapi.types import IncEx, ModelNameMap\nfrom pydantic import BaseModel, TypeAdapter, create_model\nfrom pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError\nfrom pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation\nfrom pydantic import ValidationError as ValidationError\nfrom pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined]\n GetJsonSchemaHandler as GetJsonSchemaHandler,\n)\nfrom pydantic._internal._typing_extra import eval_type_lenient\nfrom pydantic._internal._utils import lenient_issubclass as lenient_issubclass\nfrom pydantic.fields import FieldInfo as FieldInfo\nfrom pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema\nfrom pydantic.json_schema import JsonSchemaValue as JsonSchemaValue\nfrom pydantic_core import CoreSchema as CoreSchema\nfrom pydantic_core import PydanticUndefined, PydanticUndefinedType\nfrom pydantic_core import Url as Url\nfrom typing_extensions import Annotated, Literal, get_args, get_origin\n\ntry:\n from pydantic_core.core_schema import (\n with_info_plain_validator_function as with_info_plain_validator_function,\n", "stderr": "", "exit_code": 0} |
| 36 | run_command | {
"command": "grep -n \"UnionType\" fastapi/_compat/v2.py"
} | {"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}full{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}} |
| 37 | run_command | {
"command": "grep -n \"Union\" fastapi/_compat/v2.py | head -20"
} | {"status": "ok", "stdout": "14: Union,\n111: loc: Tuple[Union[int, str], ...] = (),\n112: ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:\n128: include: Unifull{"status": "ok", "stdout": "14: Union,\n111: loc: Tuple[Union[int, str], ...] = (),\n112: ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:\n128: include: Union[IncEx, None] = None,\n129: exclude: Union[IncEx, None] = None,\n186: override_mode: Union[Literal[\"validation\"], None] = (\n217: override_mode: Union[Literal[\"validation\"], None] = (\n384: if origin_type is Union: # Handle optional sequences\n421:TypeModelOrEnum = Union[Type[\"BaseModel\"], Type[Enum]]\n448: model: Type[\"BaseModel\"], known_models: Union[TypeModelSet, None] = None\n", "stderr": "", "exit_code": 0} |
| 38 | run_command | {
"command": "sed -n '1,40p' fastapi/_compat/v2.py | grep \"UnionType\""
} | {"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}full{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}} |
| 39 | run_command | {
"command": "grep -n \"UnionType\" fastapi/types.py"
} | {"status": "ok", "stdout": "8:UnionType = getattr(types, \"UnionType\", Union)\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "8:UnionType = getattr(types, \"UnionType\", Union)\n", "stderr": "", "exit_code": 0} |
| 40 | edit_file | {
"filepath": "fastapi/_compat/v2.py",
"new_string": "from fastapi.types import IncEx, ModelNameMap, UnionType\nfrom pydantic import BaseModel, TypeAdapter, create_model",
"old_string": "from fastapi.types import IncEx, ModelNameMap\nfrom pydantic import BaseModel, TypeAdapter, create_model"
} | {"status": "ok", "filepath": "fastapi/_compat/v2.py", "occurrences": 1, "strategy": "exact", "diff": "--- a/fastapi/_compat/v2.py\n+++ b/fastapi/_compat/v2.py\nfull{"status": "ok", "filepath": "fastapi/_compat/v2.py", "occurrences": 1, "strategy": "exact", "diff": "--- a/fastapi/_compat/v2.py\n+++ b/fastapi/_compat/v2.py\n@@ -17,7 +17,7 @@\n \n from fastapi._compat import may_v1, shared\n from fastapi.openapi.constants import REF_TEMPLATE\n-from fastapi.types import IncEx, ModelNameMap\n+from fastapi.types import IncEx, ModelNameMap, UnionType\n from pydantic import BaseModel, TypeAdapter, create_model\n from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError\n from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation\n", "is_truncated": false} |
| 41 | edit_file | {
"filepath": "fastapi/_compat/v2.py",
"new_string": " if origin_type is Union or origin_type is UnionType: # Handle optional sequences",
"old_string": " if origin_type is Union: # Handle optional sequences"
} | {"status": "ok", "filepath": "fastapi/_compat/v2.py", "occurrences": 1, "strategy": "exact", "diff": "--- a/fastapi/_compat/v2.py\n+++ b/fastapi/_compat/v2.py\nfull{"status": "ok", "filepath": "fastapi/_compat/v2.py", "occurrences": 1, "strategy": "exact", "diff": "--- a/fastapi/_compat/v2.py\n+++ b/fastapi/_compat/v2.py\n@@ -381,7 +381,7 @@\n \n def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:\n origin_type = get_origin(field.field_info.annotation) or field.field_info.annotation\n- if origin_type is Union: # Handle optional sequences\n+ if origin_type is Union or origin_type is UnionType: # Handle optional sequences\n union_args = get_args(field.field_info.annotation)\n for union_arg in union_args:\n if union_arg is type(None):\n", "is_truncated": false} |
| 42 | run_command | {
"command": "rm test_union_sequence.py"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 43 | run_command | {
"command": "cd /workspace && git status --short && git diff --stat"
} | {"status": "ok", "stdout": " M fastapi/_compat/v2.py\n fastapi/_compat/v2.py | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n", "stderr": "", "exit_full{"status": "ok", "stdout": " M fastapi/_compat/v2.py\n fastapi/_compat/v2.py | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n", "stderr": "", "exit_code": 0} |
| 44 | run_command | {
"command": "python3 -c \"import fastapi._compat.v2\""
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 45 | submit_patch | {} | {"status": "ok", "patch_size": 1170, "files_changed": 1}full{"status": "ok", "patch_size": 1170, "files_changed": 1} |
diff --git a/fastapi/_compat/v2.py b/fastapi/_compat/v2.py
index 543a42dd..0faa7d5a 100644
--- a/fastapi/_compat/v2.py
+++ b/fastapi/_compat/v2.py
@@ -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):
.s.........ss [100%]
=============================== warnings summary ===============================
../../../../../../kaggle/tmp/envs/overlays/starlette-0.50.0-py3-none-any/starlette/testclient.py:45
/kaggle/tmp/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
10 passed, 3 skipped, 1 warning in 0.70s