failed WRONG_FIX wrong_fix · 30 tool calls · 176 s · fastapi/fastapi
🐛 Fix internal Pydantic v1 compatibility (warnings) for Python 3.14 and Pydantic 2.12.1 The Python 3.14 tests started failing with the Pydantic v.2.12.1 release, because of the combination of https://github.com/fastapi/fastapi/pull/14168 and https://github.com/pydantic/pydantic/pull/12367. Basically we were importing Pydantic `v1` functionality even when the user had (only) Pydantic v2 installed. This was done in https://github.com/fastapi/fastapi/pull/14168 to support more easy migration from v1 to v2 by allowing mixing versions within the same app. Here, we prevent importing any `v1` functionality by creating dummy classes for Python 3.14 / Pydantic 2.12.0 onwards, which [drops support](https://github.com/pydantic/pydantic/releases/tag/v2.12.0) for `v1` and emits a [warning](https://github.com/pydantic/pydantic/pull/12367) when importing `v1` functionality. ### TODO - [x] fix coverage - [ ] check warning is still shown to users at some point, and not just swallowed by this code.
| # | Tool | Arguments | Result |
|---|---|---|---|
| 1 | run_command | {
"command": "( grep -rn 'pydantic.v1' --include=*.py . || echo '<IMPORTANT> NO MATCH FOUND. DO NOT TRY SAME COMMAND.' ) | head -40\n"
} | {"status": "ok", "stdout": "./tests/test_compat_params_v1.py:13:from fastapi.temp_pydantic_v1_params import (\n./tests/test_tutorial/test_pydantic_v1_in_v2/testfull{"status": "ok", "stdout": "./tests/test_compat_params_v1.py:13:from fastapi.temp_pydantic_v1_params import (\n./tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py:32: mod = importlib.import_module(f\"docs_src.pydantic_v1_in_v2.{request.param}\")\n./tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py:31: mod = importlib.import_module(f\"docs_src.pydantic_v1_in_v2.{request.param}\")\n./tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.py:32: mod = importlib.import_module(f\"docs_src.pydantic_v1_in_v2.{request.param}\")\n./tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py:31: mod = importlib.import_module(f\"docs_src.pydantic_v1_in_v2.{request.param}\")\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:300: \"$ref\": \"#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item\"\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:308: \"$ref\": \"#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item\"\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:322: \"$ref\": \"#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item\"\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:350: \"$ref\": \"#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input\"\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:355: \"$ref\": \"#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item\"\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:369: \"$ref\": \"#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item\"\n./tests/test_pydantic_v1_v2_multifile/test_multifile.py:399: |
| 2 | run_command | {
"command": "( grep -rn 'pydantic.v1' --include=*.py fastapi || echo '<IMPORTANT> NO MATCH FOUND. DO NOT TRY SAME COMMAND.' ) | head -40\n"
} | {"status": "ok", "stdout": "fastapi/dependencies/utils.py:51:from fastapi._compat.shared import annotation_is_pydantic_v1\nfastapi/dependencies/utils.py:79:fromfull{"status": "ok", "stdout": "fastapi/dependencies/utils.py:51:from fastapi._compat.shared import annotation_is_pydantic_v1\nfastapi/dependencies/utils.py:79:from .. import temp_pydantic_v1_params\nfastapi/dependencies/utils.py:323: param_details.field.field_info, (params.Body, temp_pydantic_v1_params.Body)\nfastapi/dependencies/utils.py:392: temp_pydantic_v1_params.Param,\nfastapi/dependencies/utils.py:394: temp_pydantic_v1_params.Body,\nfastapi/dependencies/utils.py:483: if annotation_is_pydantic_v1(use_annotation):\nfastapi/dependencies/utils.py:484: field_info = temp_pydantic_v1_params.Body(\nfastapi/dependencies/utils.py:500: field_info, (params.Path, temp_pydantic_v1_params.Path)\nfastapi/dependencies/utils.py:506: isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param))\nfastapi/dependencies/utils.py:515: if isinstance(field_info, (params.Form, temp_pydantic_v1_params.Form)):\nfastapi/dependencies/utils.py:534: elif isinstance(field_info, (params.Query, temp_pydantic_v1_params.Query)):\nfastapi/dependencies/utils.py:761: isinstance(field.field_info, (params.Form, temp_pydantic_v1_params.Form))\nfastapi/dependencies/utils.py:827: assert isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param)), (\nfastapi/dependencies/utils.py:839: assert isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param)), (\nfastapi/dependencies/utils.py:888: isinstance(first_field.field_info, (params.Form, temp_pydantic_v1_params.Form))\nfastapi/dependencies/utils.py:906: isinstance(field_info, (params.File, temp_pydantic_v1_params.File))\nfastapi/dependencies/utils.py:913: and isinstance(field_info, (params.File, temp_pydantic_v1_params.File))\nfastapi/dependencies/utils.py:1020: isinstance(f.field_info, temp_pydantic_v1_params.File)\nfastapi/dependencies/utils.py:1023: |
| 3 | run_command | {
"command": "sed -n '60,100p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": " from pydantic.schema import (\n get_annotation_from_field_info as get_annotation_from_field_info,\n )\n from pydantic.schema importfull{"status": "ok", "stdout": " from pydantic.schema import (\n get_annotation_from_field_info as get_annotation_from_field_info,\n )\n from pydantic.schema import get_flat_models_from_field as get_flat_models_from_field\n from pydantic.schema import get_model_name_map as get_model_name_map\n from pydantic.types import SecretBytes as SecretBytes\n from pydantic.types import SecretStr as SecretStr\n from pydantic.typing import evaluate_forwardref as evaluate_forwardref\n from pydantic.utils import lenient_issubclass as lenient_issubclass\n\n\nelse:\n from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]\n from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]\n from pydantic.v1 import ( # type: ignore[assignment]\n ValidationError as ValidationError,\n )\n from pydantic.v1 import create_model as create_model # type: ignore[no-redef]\n from pydantic.v1.class_validators import Validator as Validator\n from pydantic.v1.color import Color as Color # type: ignore[assignment]\n from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper\n from pydantic.v1.errors import MissingError\n from pydantic.v1.fields import (\n SHAPE_FROZENSET,\n SHAPE_LIST,\n SHAPE_SEQUENCE,\n SHAPE_SET,\n SHAPE_SINGLETON,\n SHAPE_TUPLE,\n SHAPE_TUPLE_ELLIPSIS,\n )\n from pydantic.v1.fields import FieldInfo as FieldInfo # type: ignore[assignment]\n from pydantic.v1.fields import ModelField as ModelField\n from pydantic.v1.fields import Undefined as Undefined\n from pydantic.v1.fields import UndefinedType as UndefinedType\n from pydantic.v1.networks import AnyUrl as AnyUrl\n from pydantic.v1.networks import ( # type: ignore[assignment]\n NameEmail as NameEmail,\n )\n from pydantic.v1.schema import TypeModelSet as TypeModelSet\n from pydantic.v1.schema import (\n", "stderr": "", "exit_code": 0} |
| 4 | run_command | {
"command": "sed -n '1,70p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "from copy import copy\nfrom dataclasses import dataclass, is_dataclass\nfrom enum import Enum\nfrom typing import (\n Any,\n Callablfull{"status": "ok", "stdout": "from copy import copy\nfrom dataclasses import dataclass, is_dataclass\nfrom enum import Enum\nfrom typing import (\n Any,\n Callable,\n Dict,\n List,\n Sequence,\n Set,\n Tuple,\n Type,\n Union,\n)\n\nfrom fastapi._compat import shared\nfrom fastapi.openapi.constants import REF_PREFIX as REF_PREFIX\nfrom fastapi.types import ModelNameMap\nfrom pydantic.version import VERSION as PYDANTIC_VERSION\nfrom typing_extensions import Literal\n\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2\n# Keeping old \"Required\" functionality from Pydantic V1, without\n# shadowing typing.Required.\nRequiredParam: Any = Ellipsis\n\nif not PYDANTIC_V2:\n from pydantic import BaseConfig as BaseConfig\n from pydantic import BaseModel as BaseModel\n from pydantic import ValidationError as ValidationError\n from pydantic import create_model as create_model\n from pydantic.class_validators import Validator as Validator\n from pydantic.color import Color as Color\n from pydantic.error_wrappers import ErrorWrapper as ErrorWrapper\n from pydantic.errors import MissingError\n from pydantic.fields import ( # type: ignore[attr-defined]\n SHAPE_FROZENSET,\n SHAPE_LIST,\n SHAPE_SEQUENCE,\n SHAPE_SET,\n SHAPE_SINGLETON,\n SHAPE_TUPLE,\n SHAPE_TUPLE_ELLIPSIS,\n )\n from pydantic.fields import FieldInfo as FieldInfo\n from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined]\n from pydantic.fields import Undefined as Undefined # type: ignore[attr-defined]\n from pydantic.fields import ( # type: ignore[attr-defined]\n UndefinedType as UndefinedType,\n )\n from pydantic.networks import AnyUrl as AnyUrl\n from pydantic.networks import NameEmail as NameEmail\n from pydantic.schema import TypeModelSet as TypeModelSet\n from |
| 5 | run_command | {
"command": "sed -n '70,110p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "\nelse:\n from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]\n from pydantic.v1 import BaseModel as BaseModfull{"status": "ok", "stdout": "\nelse:\n from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]\n from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]\n from pydantic.v1 import ( # type: ignore[assignment]\n ValidationError as ValidationError,\n )\n from pydantic.v1 import create_model as create_model # type: ignore[no-redef]\n from pydantic.v1.class_validators import Validator as Validator\n from pydantic.v1.color import Color as Color # type: ignore[assignment]\n from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper\n from pydantic.v1.errors import MissingError\n from pydantic.v1.fields import (\n SHAPE_FROZENSET,\n SHAPE_LIST,\n SHAPE_SEQUENCE,\n SHAPE_SET,\n SHAPE_SINGLETON,\n SHAPE_TUPLE,\n SHAPE_TUPLE_ELLIPSIS,\n )\n from pydantic.v1.fields import FieldInfo as FieldInfo # type: ignore[assignment]\n from pydantic.v1.fields import ModelField as ModelField\n from pydantic.v1.fields import Undefined as Undefined\n from pydantic.v1.fields import UndefinedType as UndefinedType\n from pydantic.v1.networks import AnyUrl as AnyUrl\n from pydantic.v1.networks import ( # type: ignore[assignment]\n NameEmail as NameEmail,\n )\n from pydantic.v1.schema import TypeModelSet as TypeModelSet\n from pydantic.v1.schema import (\n field_schema,\n get_flat_models_from_fields,\n model_process_schema,\n )\n from pydantic.v1.schema import (\n get_annotation_from_field_info as get_annotation_from_field_info,\n )\n from pydantic.v1.schema import (\n get_flat_models_from_field as get_flat_models_from_field,\n )\n", "stderr": "", "exit_code": 0} |
| 6 | run_command | {
"command": "sed -n '110,140p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": " )\n from pydantic.v1.schema import get_model_name_map as get_model_name_map\n from pydantic.v1.types import ( # type: ignore[assignfull{"status": "ok", "stdout": " )\n from pydantic.v1.schema import get_model_name_map as get_model_name_map\n from pydantic.v1.types import ( # type: ignore[assignment]\n SecretBytes as SecretBytes,\n )\n from pydantic.v1.types import ( # type: ignore[assignment]\n SecretStr as SecretStr,\n )\n from pydantic.v1.typing import evaluate_forwardref as evaluate_forwardref\n from pydantic.v1.utils import lenient_issubclass as lenient_issubclass\n\n\nGetJsonSchemaHandler = Any\nJsonSchemaValue = Dict[str, Any]\nCoreSchema = Any\nUrl = AnyUrl\n\nsequence_shapes = {\n SHAPE_LIST,\n SHAPE_SET,\n SHAPE_FROZENSET,\n SHAPE_TUPLE,\n SHAPE_SEQUENCE,\n SHAPE_TUPLE_ELLIPSIS,\n}\nsequence_shape_to_type = {\n SHAPE_LIST: list,\n SHAPE_SET: set,\n SHAPE_TUPLE: tuple,\n SHAPE_SEQUENCE: list,\n SHAPE_TUPLE_ELLIPSIS: list,\n", "stderr": "", "exit_code": 0} |
| 7 | run_command | {
"command": "python3 -c \"import sys; print(sys.version)\"\n"
} | {"status": "ok", "stdout": "3.13.15 (main, Sep 1 2026, 14:05:45) [Clang 22.1.3 ]\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "3.13.15 (main, Sep 1 2026, 14:05:45) [Clang 22.1.3 ]\n", "stderr": "", "exit_code": 0} |
| 8 | run_command | {
"command": "python3 -c \"import pydantic; print(pydantic.__version__)\"\n"
} | {"status": "ok", "stdout": "2.13.5\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "2.13.5\n", "stderr": "", "exit_code": 0} |
| 9 | run_command | {
"command": "cat > /tmp/check_pydantic_v1.py <<'PY'\ntry:\n import pydantic.v1\n print(\"Successfully imported pydantic.v1\")\nexcept ImportError as e:\n print(f\"Failed to import pydantic.v1: {e}\")\nexcept Exception as e:\n print(f\"An unexpected error occurred: {e}\")\nPY\npython3 /tmp/check_pydantic_v1.py\n"
} | {"status": "ok", "stdout": "Successfully imported pydantic.v1\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Successfully imported pydantic.v1\n", "stderr": "", "exit_code": 0} |
| 10 | run_command | {
"command": "cat > /tmp/check_pydantic_v1_warning.py <<'PY'\nimport warnings\nwith warnings.catch_warnings(record=True) as w:\n warnings.simplefilter(\"always\")\n try:\n import pydantic.v1\n print(\"Imported pydantic.v1\")\n for warning in w:\n print(f\"Warning: {warning.message}\")\n except Exception as e:\n print(f\"Error: {e}\")\nPY\npython3 /tmp/check_pydantic_v1_warning.py\n"
} | {"status": "ok", "stdout": "Imported pydantic.v1\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Imported pydantic.v1\n", "stderr": "", "exit_code": 0} |
| 11 | run_command | {
"command": "sed -n '1,20p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "from copy import copy\nfrom dataclasses import dataclass, is_dataclass\nfrom enum import Enum\nfrom typing import (\n Any,\n Callablfull{"status": "ok", "stdout": "from copy import copy\nfrom dataclasses import dataclass, is_dataclass\nfrom enum import Enum\nfrom typing import (\n Any,\n Callable,\n Dict,\n List,\n Sequence,\n Set,\n Tuple,\n Type,\n Union,\n)\n\nfrom fastapi._compat import shared\nfrom fastapi.openapi.constants import REF_PREFIX as REF_PREFIX\nfrom fastapi.types import ModelNameMap\nfrom pydantic.version import VERSION as PYDANTIC_VERSION\nfrom typing_extensions import Literal\n", "stderr": "", "exit_code": 0} |
| 12 | run_command | {
"command": "sed -n '21,30p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLfull{"status": "ok", "stdout": "\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2\n# Keeping old \"Required\" functionality from Pydantic V1, without\n# shadowing typing.Required.\nRequiredParam: Any = Ellipsis\n\nif not PYDANTIC_V2:\n from pydantic import BaseConfig as BaseConfig\n from pydantic import BaseModel as BaseModel\n", "stderr": "", "exit_code": 0} |
| 13 | run_command | {
"command": "python3 -c \"import sys; print(sys.version_info)\"\n"
} | {"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0} |
| 14 | run_command | {
"command": "python3 -c \"import pydantic; print(pydantic.version.VERSION)\"\n"
} | {"status": "ok", "stdout": "2.13.5\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "2.13.5\n", "stderr": "", "exit_code": 0} |
| 15 | run_command | {
"command": "sed -n '21,70p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLfull{"status": "ok", "stdout": "\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2\n# Keeping old \"Required\" functionality from Pydantic V1, without\n# shadowing typing.Required.\nRequiredParam: Any = Ellipsis\n\nif not PYDANTIC_V2:\n from pydantic import BaseConfig as BaseConfig\n from pydantic import BaseModel as BaseModel\n from pydantic import ValidationError as ValidationError\n from pydantic import create_model as create_model\n from pydantic.class_validators import Validator as Validator\n from pydantic.color import Color as Color\n from pydantic.error_wrappers import ErrorWrapper as ErrorWrapper\n from pydantic.errors import MissingError\n from pydantic.fields import ( # type: ignore[attr-defined]\n SHAPE_FROZENSET,\n SHAPE_LIST,\n SHAPE_SEQUENCE,\n SHAPE_SET,\n SHAPE_SINGLETON,\n SHAPE_TUPLE,\n SHAPE_TUPLE_ELLIPSIS,\n )\n from pydantic.fields import FieldInfo as FieldInfo\n from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined]\n from pydantic.fields import Undefined as Undefined # type: ignore[attr-defined]\n from pydantic.fields import ( # type: ignore[attr-defined]\n UndefinedType as UndefinedType,\n )\n from pydantic.networks import AnyUrl as AnyUrl\n from pydantic.networks import NameEmail as NameEmail\n from pydantic.schema import TypeModelSet as TypeModelSet\n from pydantic.schema import (\n field_schema,\n get_flat_models_from_fields,\n model_process_schema,\n )\n from pydantic.schema import (\n get_annotation_from_field_info as get_annotation_from_field_info,\n )\n from pydantic.schema import get_flat_models_from_field as get_flat_models_from_field\n from pydantic.schema import get_model_name_map as get_model_name_map\n from pydantic.types import SecretBytes as SecretBytes\n |
| 16 | run_command | {
"command": "python3 -c \"import sys; print(sys.version_info)\"\n"
} | {"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0} |
| 17 | run_command | {
"command": "cat > /tmp/reproduce_warning.py <<'PY'\nimport sys\nimport warnings\nfrom pydantic.version import VERSION as PYDANTIC_VERSION\n\nprint(f\"Python version: {sys.version}\")\nprint(f\"Pydantic version: {PYDANTIC_VERSION}\")\n\nwith warnings.catch_warnings(record=True) as w:\n warnings.simplefilter(\"always\")\n try:\n import pydantic.v1\n print(\"Imported pydantic.v1\")\n for warning in w:\n print(f\"Warning: {warning.message}\")\n except ImportError as e:\n print(f\"ImportError: {e}\")\nPY\npython3 /tmp/reproduce_warning.py\n"
} | {"status": "ok", "stdout": "Python version: 3.13.15 (main, Sep 1 2026, 14:05:45) [Clang 22.1.3 ]\nPydantic version: 2.13.5\nImported pydantic.v1\n", "stderr": "full{"status": "ok", "stdout": "Python version: 3.13.15 (main, Sep 1 2026, 14:05:45) [Clang 22.1.3 ]\nPydantic version: 2.13.5\nImported pydantic.v1\n", "stderr": "", "exit_code": 0} |
| 18 | run_command | {
"command": "python3 -c \"import pydantic; print(pydantic.version.VERSION)\"\n"
} | {"status": "ok", "stdout": "2.13.5\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "2.13.5\n", "stderr": "", "exit_code": 0} |
| 19 | run_command | {
"command": "python3 -c \"import sys; print(sys.version_info)\"\n"
} | {"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0} |
| 20 | run_command | {
"command": "sed -n '20,35p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "from typing_extensions import Literal\n\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYfull{"status": "ok", "stdout": "from typing_extensions import Literal\n\nPYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(\".\")[:2])\nPYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2\n# Keeping old \"Required\" functionality from Pydantic V1, without\n# shadowing typing.Required.\nRequiredParam: Any = Ellipsis\n\nif not PYDANTIC_V2:\n from pydantic import BaseConfig as BaseConfig\n from pydantic import BaseModel as BaseModel\n from pydantic import ValidationError as ValidationError\n from pydantic import create_model as create_model\n from pydantic.class_validators import Validator as Validator\n from pydantic.color import Color as Color\n from pydantic.error_wrappers import ErrorWrapper as ErrorWrapper\n", "stderr": "", "exit_code": 0} |
| 21 | run_command | {
"command": "python3 -c \"import pydantic.v1; print('OK')\"\n"
} | {"status": "ok", "stdout": "OK\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "OK\n", "stderr": "", "exit_code": 0} |
| 22 | run_command | {
"command": "sed -n '65,130p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": " from pydantic.types import SecretBytes as SecretBytes\n from pydantic.types import SecretStr as SecretStr\n from pydantic.typing imfull{"status": "ok", "stdout": " from pydantic.types import SecretBytes as SecretBytes\n from pydantic.types import SecretStr as SecretStr\n from pydantic.typing import evaluate_forwardref as evaluate_forwardref\n from pydantic.utils import lenient_issubclass as lenient_issubclass\n\n\nelse:\n from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]\n from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]\n from pydantic.v1 import ( # type: ignore[assignment]\n ValidationError as ValidationError,\n )\n from pydantic.v1 import create_model as create_model # type: ignore[no-redef]\n from pydantic.v1.class_validators import Validator as Validator\n from pydantic.v1.color import Color as Color # type: ignore[assignment]\n from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper\n from pydantic.v1.errors import MissingError\n from pydantic.v1.fields import (\n SHAPE_FROZENSET,\n SHAPE_LIST,\n SHAPE_SEQUENCE,\n SHAPE_SET,\n SHAPE_SINGLETON,\n SHAPE_TUPLE,\n SHAPE_TUPLE_ELLIPSIS,\n )\n from pydantic.v1.fields import FieldInfo as FieldInfo # type: ignore[assignment]\n from pydantic.v1.fields import ModelField as ModelField\n from pydantic.v1.fields import Undefined as Undefined\n from pydantic.v1.fields import UndefinedType as UndefinedType\n from pydantic.v1.networks import AnyUrl as AnyUrl\n from pydantic.v1.networks import ( # type: ignore[assignment]\n NameEmail as NameEmail,\n )\n from pydantic.v1.schema import TypeModelSet as TypeModelSet\n from pydantic.v1.schema import (\n field_schema,\n get_flat_models_from_fields,\n model_process_schema,\n )\n from pydantic.v1.schema import (\n get_annotation_from_field_info as get_annotation_from_field_info,\n )\n from pydantic.v1.schema import (\n get_flat_models_from_field as get_flat_models_from_ |
| 23 | run_command | {
"command": "python3 -c \"import sys; print(sys.version_info)\"\n"
} | {"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "sys.version_info(major=3, minor=13, micro=15, releaselevel='final', serial=0)\n", "stderr": "", "exit_code": 0} |
| 24 | run_command | {
"command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"fastapi/_compat/v1.py\")\ns = p.read_text()\n\n# Define the condition for Python 3.14 and Pydantic 2.12.0+\n# We need to import sys for this.\n# Also need to define dummy classes for all the v1 imports.\n\nold_condition = \"if not PYDANTIC_V2:\"\n# We will change the structure to:\n# if not PYDANTIC_V2:\n# ... (existing v1 imports)\n# elif (sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12)):\n# # dummy classes\n# else:\n# # existing pydantic.v1 imports\n\n# Actually, it might be easier to wrap the pydantic.v1 imports in another if.\n\n# Let's find where the 'else:' starts.\n# The 'else:' is on line 71 (approx).\n\n# I will add 'import sys' at the top.\n# Then I will modify the if/else block.\n\n# Original:\n# if not PYDANTIC_V2:\n# ...\n# else:\n# from pydantic.v1 import ...\n\n# New:\n# if not PYDANTIC_V2:\n# ...\n# elif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):\n# # Dummy classes\n# BaseConfig = Any\n# BaseModel = Any\n# ...\n# else:\n# from pydantic.v1 import ...\n\n# But the dummy classes need to be available for everything that uses them.\n# The current file exports them.\n\n# Let's just replace the 'else:' block.\n\n# First, add import sys.\ns = s.replace(\"from copy import copy\", \"import sys\\nfrom copy import copy\")\n\n# Now replace the 'else:' block.\n# The else block starts at 'else:\\n from pydantic.v1 import BaseConfig as BaseConfig'\n# and ends before 'GetJsonSchemaHandler = Any'\n\n# This is a large block. Let's be careful.\n\n# I will find the start of the 'else:' block.\nimport re\nmatch = re.search(r'else:\\s+from pydantic\\.v1 import BaseConfig as BaseConfig', s)\nif match:\n start = match.start()\n # Find the end of the imports\n # The imports end before 'GetJsonSchemaHandler = Any'\n end = s.find('GetJsonSchemaHandler = Any')\n \n # We want to replace the whole 'else' block.\n # But we want to keep the 'else' if the condition is not met.\n\n # Let's use a more robust replacement.\n # We will replace:\n # else:\n# from pydantic.v1 import ...\n# ...\n# from pydantic.v1.utils import lenient_issubclass as lenient_issubclass\n\n# With:\n# elif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):\n# # Dummy classes to avoid warnings/errors in Python 3.14+ and Pydantic 2.12+\n# BaseConfig = Any\n# BaseModel = Any\n# ValidationError = Any\n# create_model = Any\n# Validator = Any\n# Color = Any\n# ErrorWrapper = Any\n# MissingError = Any\n# SHAPE_FROZENSET = Any\n# SHAPE_LIST = Any\n# SHAPE_SEQUENCE = Any\n# SHAPE_SET = Any\n# SHAPE_SINGLETON = Any\n# SHAPE_TUPLE = Any\n# SHAPE_TUPLE_ELLIPSIS = Any\n# FieldInfo = Any\n# ModelField = Any\n# Undefined = Any\n# UndefinedType = Any\n# AnyUrl = Any\n# NameEmail = Any\n# TypeModelSet = Any\n# field_schema = Any\n# get_flat_models_from_fields = Any\n# model_process_schema = Any\n# get_annotation_from_field_info = Any\n# get_flat_models_from_field = Any\n# get_model_name_map = Any\n# SecretBytes = Any\n# SecretStr = Any\n# evaluate_forwardref = Any\n# lenient_issubclass = Any\n# else:\n# from pydantic.v1 import ...\n\n# Wait, I can just define these as Any and then if it's NOT (3.14 and 2.12), \n# I can override them with the actual imports.\n\n# But the existing structure is:\n# if not PYDANTIC_V2:\n# # v1 imports from pydantic\n# else:\n# # v1 imports from pydantic.v1\n\n# So I will change:\n# else:\n# from pydantic.v1 import ...\n\n# To:\n# elif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):\n# # dummy classes\n# ...\n# else:\n# from pydantic.v1 import ...\n\n# This looks correct.\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 25 | run_command | {
"command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"fastapi/_compat/v1.py\")\ns = p.read_text()\n\n# Add import sys\nif \"import sys\" not in s:\n s = s.replace(\"from copy import copy\", \"import sys\\nfrom copy import copy\")\n\n# Identify the else block to be replaced\n# The else block starts at 'else:' and contains imports from pydantic.v1\n# It ends before 'GetJsonSchemaHandler = Any'\n\nimport re\nmatch = re.search(r'else:\\n from pydantic\\.v1 import BaseConfig as BaseConfig', s)\nif match:\n start = match.start()\n end = s.find('GetJsonSchemaHandler = Any')\n else_block = s[start:end]\n \n # The imports inside the else block\n # We want to extract the names of the imported symbols.\n # This is tricky because of the multiple import styles.\n \n # Let's just define the dummy names manually based on the current code.\n dummies = [\n \"BaseConfig\", \"BaseModel\", \"ValidationError\", \"create_model\", \"Validator\",\n \"Color\", \"ErrorWrapper\", \"MissingError\", \"SHAPE_FROZENSET\", \"SHAPE_LIST\",\n \"SHAPE_SEQUENCE\", \"SHAPE_SET\", \"SHAPE_SINGLETON\", \"SHAPE_TUPLE\",\n \"SHAPE_TUPLE_ELLIPSIS\", \"FieldInfo\", \"ModelField\", \"Undefined\",\n \"UndefinedType\", \"AnyUrl\", \"NameEmail\", \"TypeModelSet\", \"field_schema\",\n \"get_flat_models_from_fields\", \"model_process_schema\",\n \"get_annotation_from_field_info\", \"get_flat_models_from_field\",\n \"get_model_name_map\", \"SecretBytes\", \"SecretStr\", \"evaluate_forwardref\",\n \"lenient_issubclass\"\n ]\n \n dummy_assignments = \"\\n\".join([f\" {name} = Any\" for name in dummies])\n \n new_block = f\"elif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):\\n{dummy_assignments}\\nelse:\\n{else_block[len('else:'):]}\"\n \n s = s[:start] + new_block + s[end:]\n\np.write_text(s)\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 26 | run_command | {
"command": "sed -n '65,150p' fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": " from pydantic.schema import get_model_name_map as get_model_name_map\n from pydantic.types import SecretBytes as SecretBytes\n fromfull{"status": "ok", "stdout": " from pydantic.schema import get_model_name_map as get_model_name_map\n from pydantic.types import SecretBytes as SecretBytes\n from pydantic.types import SecretStr as SecretStr\n from pydantic.typing import evaluate_forwardref as evaluate_forwardref\n from pydantic.utils import lenient_issubclass as lenient_issubclass\n\n\nelif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):\n BaseConfig = Any\n BaseModel = Any\n ValidationError = Any\n create_model = Any\n Validator = Any\n Color = Any\n ErrorWrapper = Any\n MissingError = Any\n SHAPE_FROZENSET = Any\n SHAPE_LIST = Any\n SHAPE_SEQUENCE = Any\n SHAPE_SET = Any\n SHAPE_SINGLETON = Any\n SHAPE_TUPLE = Any\n SHAPE_TUPLE_ELLIPSIS = Any\n FieldInfo = Any\n ModelField = Any\n Undefined = Any\n UndefinedType = Any\n AnyUrl = Any\n NameEmail = Any\n TypeModelSet = Any\n field_schema = Any\n get_flat_models_from_fields = Any\n model_process_schema = Any\n get_annotation_from_field_info = Any\n get_flat_models_from_field = Any\n get_model_name_map = Any\n SecretBytes = Any\n SecretStr = Any\n evaluate_forwardref = Any\n lenient_issubclass = Any\nelse:\n\n from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]\n from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]\n from pydantic.v1 import ( # type: ignore[assignment]\n ValidationError as ValidationError,\n )\n from pydantic.v1 import create_model as create_model # type: ignore[no-redef]\n from pydantic.v1.class_validators import Validator as Validator\n from pydantic.v1.color import Color as Color # type: ignore[assignment]\n from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper\n from pydantic.v1.errors import MissingError\n from pydantic.v1.fields import (\n SHAPE_FROZENSET,\n SHAPE_LIST,\n SHAP |
| 27 | run_command | {
"command": "python3 -m py_compile fastapi/_compat/v1.py\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 28 | run_command | {
"command": "python3 -c \"import fastapi._compat.v1; print('OK')\"\n"
} | {"status": "ok", "stdout": "OK\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "OK\n", "stderr": "", "exit_code": 0} |
| 29 | run_command | {
"command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"fastapi/_compat/v1.py\")\ns = p.read_text()\n# Remove the extra newline after 'else:'\ns = s.replace(\"else:\\n\\n from pydantic.v1 import BaseConfig as BaseConfig\", \"else:\\n from pydantic.v1 import BaseConfig as BaseConfig\")\np.write_text(s)\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 30 | run_command | {
"command": "git diff\n"
} | {"status": "ok", "stdout": "diff --git a/fastapi/_compat/v1.py b/fastapi/_compat/v1.py\nindex f0ac5163..c422df9e 100644\n--- a/fastapi/_compat/v1.py\n+++ b/fastfull{"status": "ok", "stdout": "diff --git a/fastapi/_compat/v1.py b/fastapi/_compat/v1.py\nindex f0ac5163..c422df9e 100644\n--- a/fastapi/_compat/v1.py\n+++ b/fastapi/_compat/v1.py\n@@ -1,3 +1,4 @@\n+import sys\n from copy import copy\n from dataclasses import dataclass, is_dataclass\n from enum import Enum\n@@ -68,6 +69,39 @@ if not PYDANTIC_V2:\n from pydantic.utils import lenient_issubclass as lenient_issubclass\n \n \n+elif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):\n+ BaseConfig = Any\n+ BaseModel = Any\n+ ValidationError = Any\n+ create_model = Any\n+ Validator = Any\n+ Color = Any\n+ ErrorWrapper = Any\n+ MissingError = Any\n+ SHAPE_FROZENSET = Any\n+ SHAPE_LIST = Any\n+ SHAPE_SEQUENCE = Any\n+ SHAPE_SET = Any\n+ SHAPE_SINGLETON = Any\n+ SHAPE_TUPLE = Any\n+ SHAPE_TUPLE_ELLIPSIS = Any\n+ FieldInfo = Any\n+ ModelField = Any\n+ Undefined = Any\n+ UndefinedType = Any\n+ AnyUrl = Any\n+ NameEmail = Any\n+ TypeModelSet = Any\n+ field_schema = Any\n+ get_flat_models_from_fields = Any\n+ model_process_schema = Any\n+ get_annotation_from_field_info = Any\n+ get_flat_models_from_field = Any\n+ get_model_name_map = Any\n+ SecretBytes = Any\n+ SecretStr = Any\n+ evaluate_forwardref = Any\n+ lenient_issubclass = Any\n else:\n from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]\n from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]\n", "stderr": "", "exit_code": 0} |
| 31 | submit_patch | {} | {"status": "ok", "patch_size": 1454, "files_changed": 1}full{"status": "ok", "patch_size": 1454, "files_changed": 1} |
diff --git a/fastapi/_compat/v1.py b/fastapi/_compat/v1.py
index f0ac5163..c422df9e 100644
--- a/fastapi/_compat/v1.py
+++ b/fastapi/_compat/v1.py
@@ -1,3 +1,4 @@
+import sys
from copy import copy
from dataclasses import dataclass, is_dataclass
from enum import Enum
@@ -68,6 +69,39 @@ if not PYDANTIC_V2:
from pydantic.utils import lenient_issubclass as lenient_issubclass
+elif sys.version_info >= (3, 14) and PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):
+ BaseConfig = Any
+ BaseModel = Any
+ ValidationError = Any
+ create_model = Any
+ Validator = Any
+ Color = Any
+ ErrorWrapper = Any
+ MissingError = Any
+ SHAPE_FROZENSET = Any
+ SHAPE_LIST = Any
+ SHAPE_SEQUENCE = Any
+ SHAPE_SET = Any
+ SHAPE_SINGLETON = Any
+ SHAPE_TUPLE = Any
+ SHAPE_TUPLE_ELLIPSIS = Any
+ FieldInfo = Any
+ ModelField = Any
+ Undefined = Any
+ UndefinedType = Any
+ AnyUrl = Any
+ NameEmail = Any
+ TypeModelSet = Any
+ field_schema = Any
+ get_flat_models_from_fields = Any
+ model_process_schema = Any
+ get_annotation_from_field_info = Any
+ get_flat_models_from_field = Any
+ get_model_name_map = Any
+ SecretBytes = Any
+ SecretStr = Any
+ evaluate_forwardref = Any
+ lenient_issubclass = Any
else:
from pydantic.v1 import BaseConfig as BaseConfig # type: ignore[assignment]
from pydantic.v1 import BaseModel as BaseModel # type: ignore[assignment]
==================================== ERRORS ====================================
____________________ ERROR collecting tests/test_compat.py _____________________
ImportError while importing test module '/private/tmp/swe_work/pod_r5_v1i/fastapi_14186/b/workspace/tests/test_compat.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Users/jp/.local/share/uv/python/cpython-3.13.15-macos-aarch64-none/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/test_compat.py:4: in <module>
from fastapi._compat import (
E ImportError: cannot import name 'may_v1' from 'fastapi._compat' (/private/tmp/swe_work/pod_r5_v1i/fastapi_14186/b/workspace/fastapi/_compat/__init__.py)
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 error in 0.40s