failed NO_PATCH NO_PATCH UNSUBMITTED empty_patch(budget) ยท 43 tool calls ยท 305 s ยท fastapi/fastapi
๐ Fix separation of schemas with nested models introduced in 0.119.0 ๐ Fix separation of schemas with nested models introduced in 0.119.0 This should fix / related to https://github.com/fastapi/fastapi/issues/14247 (https://github.com/fastapi/fastapi/discussions/14177)
| # | Tool | Arguments | Result |
|---|---|---|---|
| 1 | run_command | {
"command": "grep -rn \"separation of schemas\" ."
} | {"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}} |
| 2 | run_command | {
"command": "grep -rn \"nested models\" fastapi | head -20"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 3 | run_command | {
"command": "grep -rn \"response_model\" fastapi/utils.py | head -20"
} | {"status": "ok", "stdout": "fastapi/utils.py:71: \"parameter response_model=None. Read more: \"\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "fastapi/utils.py:71: \"parameter response_model=None. Read more: \"\n", "stderr": "", "exit_code": 0} |
| 4 | run_command | {
"command": "grep -rn \"response_model\" fastapi/routing.py | head -20"
} | {"status": "ok", "stdout": "fastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:301: response_model_exclude: Optional[Infull{"status": "ok", "stdout": "fastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:301: response_model_exclude: Optional[IncEx] = None,\nfastapi/routing.py:302: response_model_by_alias: bool = True,\nfastapi/routing.py:303: response_model_exclude_unset: bool = False,\nfastapi/routing.py:304: response_model_exclude_defaults: bool = False,\nfastapi/routing.py:305: response_model_exclude_none: bool = False,\nfastapi/routing.py:415: include=response_model_include,\nfastapi/routing.py:416: exclude=response_model_exclude,\nfastapi/routing.py:417: by_alias=response_model_by_alias,\nfastapi/routing.py:418: exclude_unset=response_model_exclude_unset,\nfastapi/routing.py:419: exclude_defaults=response_model_exclude_defaults,\nfastapi/routing.py:420: exclude_none=response_model_exclude_none,\nfastapi/routing.py:513: response_model: Any = Default(None),\nfastapi/routing.py:525: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:526: response_model_exclude: Optional[IncEx] = None,\nfastapi/routing.py:527: response_model_by_alias: bool = True,\nfastapi/routing.py:528: response_model_exclude_unset: bool = False,\nfastapi/routing.py:529: response_model_exclude_defaults: bool = False,\nfastapi/routing.py:530: response_model_exclude_none: bool = False,\nfastapi/routing.py:544: if isinstance(response_model, DefaultPlaceholder):\n", "stderr": "", "exit_code": 0} |
| 5 | run_command | {
"command": "grep -rn \"response_model\" fastapi/routing.py -A 20 | grep -C 5 \"response_model\" | head -40"
} | {"status": "ok", "stdout": "fastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:301: response_model_exclude: Optional[Infull{"status": "ok", "stdout": "fastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:301: response_model_exclude: Optional[IncEx] = None,\nfastapi/routing.py:302: response_model_by_alias: bool = True,\nfastapi/routing.py:303: response_model_exclude_unset: bool = False,\nfastapi/routing.py:304: response_model_exclude_defaults: bool = False,\nfastapi/routing.py:305: response_model_exclude_none: bool = False,\nfastapi/routing.py-306- dependency_overrides_provider: Optional[Any] = None,\nfastapi/routing.py-307- embed_body_fields: bool = False,\nfastapi/routing.py-308-) -> Callable[[Request], Coroutine[Any, Any, Response]]:\nfastapi/routing.py-309- assert dependant.call is not None, \"dependant.call must be a function\"\nfastapi/routing.py-310- is_coroutine = iscoroutinefunction(dependant.call)\n--\nfastapi/routing.py-322- assert isinstance(file_stack, AsyncExitStack), (\nfastapi/routing.py-323- \"fastapi_middleware_astack not found in request scope\"\nfastapi/routing.py-324- )\nfastapi/routing.py-325-\n--\nfastapi/routing.py:415: include=response_model_include,\nfastapi/routing.py:416: exclude=response_model_exclude,\nfastapi/routing.py:417: by_alias=response_model_by_alias,\nfastapi/routing.py:418: exclude_unset=response_model_exclude_unset,\nfastapi/routing.py:419: exclude_defaults=response_model_exclude_defaults,\nfastapi/routing.py:420: exclude_none=response_model_exclude_none,\nfastapi/routing.py-421- is_coroutine=is_coroutine,\nfastapi/routing.py-422- )\nfastapi/routing.py-423- response = actual_response_class(content, **response_args)\nfastapi/routing.py-424- if not is_body_allowed_for_status_code(response.status_code):\nfastapi/routing.py-425- response.body = b\"\"\n--\nfastapi/ro |
| 6 | run_command | {
"command": "grep -rn \"response_model\" fastapi/routing.py -C 5 | grep -C 5 \"response_model\" | head -100"
} | {"status": "ok", "stdout": "fastapi/routing.py-295- dependant: Dependant,\nfastapi/routing.py-296- body_field: Optional[ModelField] = None,\nfastapi/routing.py-full{"status": "ok", "stdout": "fastapi/routing.py-295- dependant: Dependant,\nfastapi/routing.py-296- body_field: Optional[ModelField] = None,\nfastapi/routing.py-297- status_code: Optional[int] = None,\nfastapi/routing.py-298- response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse),\nfastapi/routing.py-299- response_field: Optional[ModelField] = None,\nfastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:301: response_model_exclude: Optional[IncEx] = None,\nfastapi/routing.py:302: response_model_by_alias: bool = True,\nfastapi/routing.py:303: response_model_exclude_unset: bool = False,\nfastapi/routing.py:304: response_model_exclude_defaults: bool = False,\nfastapi/routing.py:305: response_model_exclude_none: bool = False,\nfastapi/routing.py-306- dependency_overrides_provider: Optional[Any] = None,\nfastapi/routing.py-307- embed_body_fields: bool = False,\nfastapi/routing.py-308-) -> Callable[[Request], Coroutine[Any, Any, Response]]:\nfastapi/routing.py-309- assert dependant.call is not None, \"dependant.call must be a function\"\nfastapi/routing.py-310- is_coroutine = iscoroutinefunction(dependant.call)\n--\nfastapi/routing.py-410- if solved_result.response.status_code:\nfastapi/routing.py-411- response_args[\"status_code\"] = solved_result.response.status_code\nfastapi/routing.py-412- content = await serialize_response(\nfastapi/routing.py-413- field=response_field,\nfastapi/routing.py-414- response_content=raw_response,\nfastapi/routing.py:415: include=response_model_include,\nfastapi/routing.py:416: exclude=response_model_exclude,\nfastapi/routing.py:417: by_alias=response_model_by_alias,\nfastapi/routing.py:418: exclude_unset=response_model_exclude_unset,\nfastapi/routing.py:419: |
| 7 | run_command | {
"command": "grep -rn \"serialize_response\" fastapi | head -20"
} | {"status": "ok", "stdout": "fastapi/routing.py:220:async def serialize_response(\nfastapi/routing.py:412: content = await serialize_response(\n", "stderr": "", full{"status": "ok", "stdout": "fastapi/routing.py:220:async def serialize_response(\nfastapi/routing.py:412: content = await serialize_response(\n", "stderr": "", "exit_code": 0} |
| 8 | run_command | {
"command": "sed -n '220,300p' fastapi/routing.py"
} | {"status": "ok", "stdout": "async def serialize_response(\n *,\n field: Optional[ModelField] = None,\n response_content: Any,\n include: Optional[IncEx] = None,full{"status": "ok", "stdout": "async def serialize_response(\n *,\n field: Optional[ModelField] = None,\n response_content: Any,\n include: Optional[IncEx] = None,\n exclude: Optional[IncEx] = None,\n by_alias: bool = True,\n exclude_unset: bool = False,\n exclude_defaults: bool = False,\n exclude_none: bool = False,\n is_coroutine: bool = True,\n) -> Any:\n if field:\n errors = []\n if not hasattr(field, \"serialize\"):\n # pydantic v1\n response_content = _prepare_response_content(\n response_content,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n if is_coroutine:\n value, errors_ = field.validate(response_content, {}, loc=(\"response\",))\n else:\n value, errors_ = await run_in_threadpool(\n field.validate, response_content, {}, loc=(\"response\",)\n )\n if isinstance(errors_, list):\n errors.extend(errors_)\n elif errors_:\n errors.append(errors_)\n if errors:\n raise ResponseValidationError(\n errors=_normalize_errors(errors), body=response_content\n )\n\n if hasattr(field, \"serialize\"):\n return field.serialize(\n value,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n\n return jsonable_encoder(\n value,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n else:\n return jsonable_e |
| 9 | run_command | {
"command": "grep -rn \"response_model\" fastapi/routing.py -C 10 | grep -C 10 \"response_model\" | head -100"
} | {"status": "ok", "stdout": "fastapi/routing.py-290- else:\nfastapi/routing.py-291- return await run_in_threadpool(dependant.call, **values)\nfastapi/routing.py-full{"status": "ok", "stdout": "fastapi/routing.py-290- else:\nfastapi/routing.py-291- return await run_in_threadpool(dependant.call, **values)\nfastapi/routing.py-292-\nfastapi/routing.py-293-\nfastapi/routing.py-294-def get_request_handler(\nfastapi/routing.py-295- dependant: Dependant,\nfastapi/routing.py-296- body_field: Optional[ModelField] = None,\nfastapi/routing.py-297- status_code: Optional[int] = None,\nfastapi/routing.py-298- response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse),\nfastapi/routing.py-299- response_field: Optional[ModelField] = None,\nfastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:301: response_model_exclude: Optional[IncEx] = None,\nfastapi/routing.py:302: response_model_by_alias: bool = True,\nfastapi/routing.py:303: response_model_exclude_unset: bool = False,\nfastapi/routing.py:304: response_model_exclude_defaults: bool = False,\nfastapi/routing.py:305: response_model_exclude_none: bool = False,\nfastapi/routing.py-306- dependency_overrides_provider: Optional[Any] = None,\nfastapi/routing.py-307- embed_body_fields: bool = False,\nfastapi/routing.py-308-) -> Callable[[Request], Coroutine[Any, Any, Response]]:\nfastapi/routing.py-309- assert dependant.call is not None, \"dependant.call must be a function\"\nfastapi/routing.py-310- is_coroutine = iscoroutinefunction(dependant.call)\nfastapi/routing.py-311- is_body_form = body_field and isinstance(\nfastapi/routing.py-312- body_field.field_info, (params.Form, temp_pydantic_v1_params.Form)\nfastapi/routing.py-313- )\nfastapi/routing.py-314- if isinstance(response_class, DefaultPlaceholder):\nfastapi/routing.py-315- actual_response_class: Type[Response] = response_class.value\n--\nfastapi/routing.py-405- current_status_code = (\nfastapi/routing.py-406- status_code if status_code else solved_result.response.status_c |
| 10 | run_command | {
"command": "grep -rn \"response_model_include\" fastapi/routing.py | head -20"
} | {"status": "ok", "stdout": "fastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:415: include=response_model_include,\nfafull{"status": "ok", "stdout": "fastapi/routing.py:300: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:415: include=response_model_include,\nfastapi/routing.py:525: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:555: self.response_model_include = response_model_include\nfastapi/routing.py:657: response_model_include=self.response_model_include,\nfastapi/routing.py:976: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:1026: response_model_include=response_model_include,\nfastapi/routing.py:1057: response_model_include: Optional[IncEx] = None,\nfastapi/routing.py:1087: response_model_include=response_model_include,\nfastapi/routing.py:1395: response_model_include=route.response_model_include,\nfastapi/routing.py:1611: response_model_include: Annotated[\nfastapi/routing.py:1619: [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).\nfastapi/routing.py:1631: [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).\nfastapi/routing.py:1643: [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).\nfastapi/routing.py:1808: response_model_include=response_model_include,\nfastapi/routing.py:1988: response_model_include: Annotated[\nfastapi/routing.py:1996: [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).\nfastapi/routing.py:2008: [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-m |
| 11 | run_command | {
"command": "cat > /tmp/repro.py <<'PY'\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\nfrom pydantic import BaseModel\nfrom typing import List\n\napp = FastAPI()\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\n@app.get(\"/user\", response_model=User, response_model_include={\"username\": True, \"items\": {\"name\": True}})\nasync def get_user():\n return {\n \"username\": \"johndoe\",\n \"items\": [\n {\"name\": \"item1\", \"description\": \"desc1\"},\n {\"name\": \"item2\", \"description\": \"desc2\"},\n ]\n }\n\nclient = TestClient(app)\n\ndef test_nested_include():\n response = client.get(\"/user\")\n print(response.json())\n assert response.json() == {\"username\": \"johndoe\", \"items\": [{\"name\": \"item1\"}, {\"name\": \"item2\"}]}\n\nif __name__ == \"__main__\":\n test_nested_include()\nPY\npython3 /tmp/repro.py\n"
} | {"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"/tmp/repro.py\", line 34, in <module>\n test_nesfull{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"/tmp/repro.py\", line 34, in <module>\n test_nested_include()\n ~~~~~~~~~~~~~~~~~~~^^\n File \"/tmp/repro.py\", line 31, in test_nested_include\n assert response.json() == {\"username\": \"johndoe\", \"items\": [{\"name\": \"item1\"}, {\"name\": \"item2\"}]}\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAssertionError\n", "details": {"stdout": "{'username': 'johndoe', 'items': []}\n", "stderr": "Traceback (most recent call last):\n File \"/tmp/repro.py\", line 34, in <module>\n test_nested_include()\n ~~~~~~~~~~~~~~~~~~~^^\n File \"/tmp/repro.py\", line 31, in test_nested_include\n assert response.json() == {\"username\": \"johndoe\", \"items\": [{\"name\": \"item1\"}, {\"name\": \"item2\"}]}\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAssertionError\n", "exit_code": 1}} |
| 12 | run_command | {
"command": "cat > /tmp/repro_v2.py <<'PY'\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\nfrom pydantic import BaseModel\nfrom typing import List\n\napp = FastAPI()\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\n@app.get(\"/user\", response_model=User, response_model_include={\"username\": True, \"items\": {\"name\": True}})\nasync def get_user():\n return {\n \"username\": \"johndoe\",\n \"items\": [\n {\"name\": \"item1\", \"description\": \"desc1\"},\n {\"name\": \"item2\", \"description\": \"desc2\"},\n ]\n }\n\nclient = TestClient(app)\n\ndef test_nested_include():\n response = client.get(\"/user\")\n print(f\"Response: {response.json()}\")\n # The issue is that items is empty.\n # Let's see what happens if we don't use response_model_include\n # But we want to test the fix for response_model_include with nested models.\n # If it's working, it should be {\"username\": \"johndoe\", \"items\": [{\"name\": \"item1\"}, {\"name\": \"item2\"}]}\n # If it's broken, it might be {\"username\": \"johndoe\", \"items\": []} or something else.\n # The reported issue is \"separation of schemas with nested models\".\n\nif __name__ == \"__main__\":\n test_nested_include()\nPY\npython3 /tmp/repro_v2.py\n"
} | {"status": "ok", "stdout": "Response: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Response: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0} |
| 13 | run_command | {
"command": "cat > /tmp/repro_v3.py <<'PY'\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\nfrom pydantic import BaseModel\nfrom typing import List\n\napp = FastAPI()\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\n@app.get(\"/user\", response_model=User, response_model_include={\"username\": True, \"items\": True})\nasync def get_user():\n return {\n \"username\": \"johndoe\",\n \"items\": [\n {\"name\": \"item1\", \"description\": \"desc1\"},\n {\"name\": \"item2\", \"description\": \"desc2\"},\n ]\n }\n\nclient = TestClient(app)\n\ndef test_nested_include():\n response = client.get(\"/user\")\n print(f\"Response: {response.json()}\")\n\nif __name__ == \"__main__\":\n test_nested_include()\nPY\npython3 /tmp/repro_v3.py\n"
} | {"status": "ok", "stdout": "Response: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\nfull{"status": "ok", "stdout": "Response: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\n", "stderr": "", "exit_code": 0} |
| 14 | run_command | {
"command": "cat > /tmp/repro_v4.py <<'PY'\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\nfrom pydantic import BaseModel\nfrom typing import List\n\napp = FastAPI()\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\n@app.get(\"/user\", response_model=User, response_model_include={\"username\": True, \"items\": {\"name\": True}})\nasync def get_user():\n return {\n \"username\": \"johndoe\",\n \"items\": [\n {\"name\": \"item1\", \"description\": \"desc1\"},\n {\"name\": \"item2\", \"description\": \"desc2\"},\n ]\n }\n\nclient = TestClient(app)\n\ndef test_nested_include():\n response = client.get(\"/user\")\n print(f\"Response: {response.json()}\")\n\nif __name__ == \"__main__\":\n test_nested_include()\nPY\npython3 /tmp/repro_v4.py\n"
} | {"status": "ok", "stdout": "Response: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Response: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0} |
| 15 | run_command | {
"command": "sed -n '220,280p' fastapi/routing.py"
} | {"status": "ok", "stdout": "async def serialize_response(\n *,\n field: Optional[ModelField] = None,\n response_content: Any,\n include: Optional[IncEx] = None,full{"status": "ok", "stdout": "async def serialize_response(\n *,\n field: Optional[ModelField] = None,\n response_content: Any,\n include: Optional[IncEx] = None,\n exclude: Optional[IncEx] = None,\n by_alias: bool = True,\n exclude_unset: bool = False,\n exclude_defaults: bool = False,\n exclude_none: bool = False,\n is_coroutine: bool = True,\n) -> Any:\n if field:\n errors = []\n if not hasattr(field, \"serialize\"):\n # pydantic v1\n response_content = _prepare_response_content(\n response_content,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n if is_coroutine:\n value, errors_ = field.validate(response_content, {}, loc=(\"response\",))\n else:\n value, errors_ = await run_in_threadpool(\n field.validate, response_content, {}, loc=(\"response\",)\n )\n if isinstance(errors_, list):\n errors.extend(errors_)\n elif errors_:\n errors.append(errors_)\n if errors:\n raise ResponseValidationError(\n errors=_normalize_errors(errors), body=response_content\n )\n\n if hasattr(field, \"serialize\"):\n return field.serialize(\n value,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n\n return jsonable_encoder(\n value,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n else:\n return jsonable_e |
| 16 | run_command | {
"command": "grep -n \"jsonable_encoder\" fastapi/routing.py"
} | {"status": "ok", "stdout": "48:from fastapi.encoders import jsonable_encoder\n268: return jsonable_encoder(\n278: return jsonable_encoder(response_content)\n", full{"status": "ok", "stdout": "48:from fastapi.encoders import jsonable_encoder\n268: return jsonable_encoder(\n278: return jsonable_encoder(response_content)\n", "stderr": "", "exit_code": 0} |
| 17 | run_command | {
"command": "sed -n '260,280p' fastapi/routing.py"
} | {"status": "ok", "stdout": " include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclfull{"status": "ok", "stdout": " include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n\n return jsonable_encoder(\n value,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n )\n else:\n return jsonable_encoder(response_content)\n\n\n", "stderr": "", "exit_code": 0} |
| 18 | run_command | {
"command": "grep -rn \"jsonable_encoder\" fastapi/encoders.py | head -20"
} | {"status": "ok", "stdout": "fastapi/encoders.py:110:def jsonable_encoder(\nfastapi/encoders.py:243: return jsonable_encoder(\nfastapi/encoders.py:254: return jsfull{"status": "ok", "stdout": "fastapi/encoders.py:110:def jsonable_encoder(\nfastapi/encoders.py:243: return jsonable_encoder(\nfastapi/encoders.py:254: return jsonable_encoder(\nfastapi/encoders.py:290: encoded_key = jsonable_encoder(\nfastapi/encoders.py:298: encoded_value = jsonable_encoder(\nfastapi/encoders.py:312: jsonable_encoder(\nfastapi/encoders.py:342: return jsonable_encoder(\n", "stderr": "", "exit_code": 0} |
| 19 | run_command | {
"command": "sed -n '110,200p' fastapi/encoders.py"
} | {"status": "ok", "stdout": "def jsonable_encoder(\n obj: Annotated[\n Any,\n Doc(\n \"\"\"\n The input object to convert to JSON.\n \"\"\"\n ),\n ],\n include: full{"status": "ok", "stdout": "def jsonable_encoder(\n obj: Annotated[\n Any,\n Doc(\n \"\"\"\n The input object to convert to JSON.\n \"\"\"\n ),\n ],\n include: Annotated[\n Optional[IncEx],\n Doc(\n \"\"\"\n Pydantic's `include` parameter, passed to Pydantic models to set the\n fields to include.\n \"\"\"\n ),\n ] = None,\n exclude: Annotated[\n Optional[IncEx],\n Doc(\n \"\"\"\n Pydantic's `exclude` parameter, passed to Pydantic models to set the\n fields to exclude.\n \"\"\"\n ),\n ] = None,\n by_alias: Annotated[\n bool,\n Doc(\n \"\"\"\n Pydantic's `by_alias` parameter, passed to Pydantic models to define if\n the output should use the alias names (when provided) or the Python\n attribute names. In an API, if you set an alias, it's probably because you\n want to use it in the result, so you probably want to leave this set to\n `True`.\n \"\"\"\n ),\n ] = True,\n exclude_unset: Annotated[\n bool,\n Doc(\n \"\"\"\n Pydantic's `exclude_unset` parameter, passed to Pydantic models to define\n if it should exclude from the output the fields that were not explicitly\n set (and that only had their default values).\n \"\"\"\n ),\n ] = False,\n exclude_defaults: Annotated[\n bool,\n Doc(\n \"\"\"\n Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define\n if it should exclude from the output the fields that had the same default\n value, even when they were explicitly set.\n \"\"\"\n ),\n ] = False,\n exclude_none: Annotated[\n bool,\n Doc(\n \"\"\"\n P |
| 20 | run_command | {
"command": "sed -n '200,350p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " \"\"\"\n Convert any object to something that can be encoded in JSON.\n\n This is used internally by FastAPI to make sure anything full{"status": "ok", "stdout": " \"\"\"\n Convert any object to something that can be encoded in JSON.\n\n This is used internally by FastAPI to make sure anything you return can be\n encoded as JSON before it is sent to the client.\n\n You can also use it yourself, for example to convert objects before saving them\n in a database that supports only JSON.\n\n Read more about it in the\n [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/).\n \"\"\"\n custom_encoder = custom_encoder or {}\n if custom_encoder:\n if type(obj) in custom_encoder:\n return custom_encoder[type(obj)](obj)\n else:\n for encoder_type, encoder_instance in custom_encoder.items():\n if isinstance(obj, encoder_type):\n return encoder_instance(obj)\n if include is not None and not isinstance(include, (set, dict)):\n include = set(include)\n if exclude is not None and not isinstance(exclude, (set, dict)):\n exclude = set(exclude)\n if isinstance(obj, (BaseModel, may_v1.BaseModel)):\n # TODO: remove when deprecating Pydantic v1\n encoders: Dict[Any, Any] = {}\n if isinstance(obj, may_v1.BaseModel):\n encoders = getattr(obj.__config__, \"json_encoders\", {}) # type: ignore[attr-defined]\n if custom_encoder:\n encoders = {**encoders, **custom_encoder}\n obj_dict = _model_dump(\n obj,\n mode=\"json\",\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n exclude_defaults=exclude_defaults,\n )\n if \"__root__\" in obj_dict:\n obj_dict = obj_dict[\"__root__\"]\n return jsonable_encoder(\n obj_dict,\n exclude_none=exclude_none,\n exclude_defaults=exclude_defaults,\n |
| 21 | run_command | {
"command": "sed -n '220,240p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " if include is not None and not isinstance(include, (set, dict)):\n include = set(include)\n if exclude is not None and not isinstanfull{"status": "ok", "stdout": " if include is not None and not isinstance(include, (set, dict)):\n include = set(include)\n if exclude is not None and not isinstance(exclude, (set, dict)):\n exclude = set(exclude)\n if isinstance(obj, (BaseModel, may_v1.BaseModel)):\n # TODO: remove when deprecating Pydantic v1\n encoders: Dict[Any, Any] = {}\n if isinstance(obj, may_v1.BaseModel):\n encoders = getattr(obj.__config__, \"json_encoders\", {}) # type: ignore[attr-defined]\n if custom_encoder:\n encoders = {**encoders, **custom_encoder}\n obj_dict = _model_dump(\n obj,\n mode=\"json\",\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n exclude_defaults=exclude_defaults,\n )\n", "stderr": "", "exit_code": 0} |
| 22 | run_command | {
"command": "sed -n '241,260p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " if \"__root__\" in obj_dict:\n obj_dict = obj_dict[\"__root__\"]\n return jsonable_encoder(\n obj_dict,\n exclude_none=exclude_nonefull{"status": "ok", "stdout": " if \"__root__\" in obj_dict:\n obj_dict = obj_dict[\"__root__\"]\n return jsonable_encoder(\n obj_dict,\n exclude_none=exclude_none,\n exclude_defaults=exclude_defaults,\n # TODO: remove when deprecating Pydantic v1\n custom_encoder=encoders,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n if dataclasses.is_dataclass(obj):\n assert not isinstance(obj, type)\n obj_dict = dataclasses.asdict(obj)\n return jsonable_encoder(\n obj_dict,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n", "stderr": "", "exit_code": 0} |
| 23 | run_command | {
"command": "sed -n '280,320p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " for key, value in obj.items():\n if (\n (\n not sqlalchemy_safe\n or (not isinstance(key, str))\n or (not key.startswith(\"_sa\"))\full{"status": "ok", "stdout": " for key, value in obj.items():\n if (\n (\n not sqlalchemy_safe\n or (not isinstance(key, str))\n or (not key.startswith(\"_sa\"))\n )\n and (value is not None or not exclude_none)\n and key in allowed_keys\n ):\n encoded_key = jsonable_encoder(\n key,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n encoded_value = jsonable_encoder(\n value,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n encoded_dict[encoded_key] = encoded_value\n return encoded_dict\n if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):\n encoded_list = []\n for item in obj:\n encoded_list.append(\n jsonable_encoder(\n item,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n", "stderr": "", "exit_code": 0} |
| 24 | run_command | {
"command": "python3 - <<'PY'\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\nprint(f\"Full: {jsonable_encoder(user)}\")\nprint(f\"Include username: {jsonable_encoder(user, include={'username': True})}\")\nprint(f\"Include nested: {jsonable_encoder(user, include={'username': True, 'items': {'name': True}})}\")\nPY\n"
} | {"status": "ok", "stdout": "Full: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\nInclfull{"status": "ok", "stdout": "Full: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\nInclude username: {'username': 'johndoe'}\nInclude nested: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0} |
| 25 | run_command | {
"command": "python3 - <<'PY'\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Let's see what happens if we use a dict instead of a BaseModel\nuser_dict = {\"username\": \"johndoe\", \"items\": [{\"name\": \"item1\", \"description\": \"desc1\"}, {\"name\": \"item2\", \"description\": \"desc2\"}]}\nprint(f\"Dict nested: {jsonable_encoder(user_dict, include={'username': True, 'items': {'name': True}})}\")\nPY\n"
} | {"status": "ok", "stdout": "Dict nested: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]full{"status": "ok", "stdout": "Dict nested: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\n", "stderr": "", "exit_code": 0} |
| 26 | run_command | {
"command": "python3 - <<'PY'\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# The issue is in jsonable_encoder when obj is a BaseModel.\n# It calls _model_dump(obj, include=include, ...)\n# Then it calls jsonable_encoder(obj_dict, ...) but DOES NOT pass include/exclude to the recursive call.\n\n# Let's verify this hypothesis.\n# In fastapi/encoders.py:\n# 248: obj_dict = _model_dump(\n# 249: obj,\n# 250: mode=\"json\",\n# 251: include=include,\n# 252: exclude=exclude,\n# ...\n# 257: )\n# 258: if \"__root__\" in obj_dict:\n# 259: obj_dict = obj_dict[\"__root__\"]\n# 260: return jsonable_encoder(\n# 261: obj_dict,\n# 262: exclude_none=exclude_none,\n# 263: exclude_defaults=exclude_defaults,\n# 264: custom_encoder=encoders,\n# 265: sqlalchemy_safe=sqlalchemy_safe,\n# 266: )\n\n# If include is {'username': True, 'items': {'name': True}},\n# _model_dump(user, include=include) will return {'username': 'johndoe', 'items': [{'name': 'item1'}, {'name': 'item2'}]}\n# Wait, if _model_dump already did the inclusion, why is the result empty?\n\n# Let's check what _model_dump returns.\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 27 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\ninclude = {'username': True, 'items': {'name': True}}\nprint(f\"Model dump: {user.model_dump(include=include)}\")\nPY\n"
} | {"status": "ok", "stdout": "Model dump: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Model dump: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0} |
| 28 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\ninclude = {'username': True, 'items': {'name': True}}\nprint(f\"Model dump: {user.model_dump(include=include)}\")\n\n# Try with a different include format\ninclude_set = {'username', 'items'}\nprint(f\"Model dump set: {user.model_dump(include=include_set)}\")\nPY\n"
} | {"status": "ok", "stdout": "Model dump: {'username': 'johndoe', 'items': []}\nModel dump set: {'username': 'johndoe', 'items': [{'name': 'item1', 'description':full{"status": "ok", "stdout": "Model dump: {'username': 'johndoe', 'items': []}\nModel dump set: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\n", "stderr": "", "exit_code": 0} |
| 29 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Pydantic v2 nested include should be:\ninclude = {'username': True, 'items': {'name': True}}\n# Wait, maybe it should be:\n# include = {'username': True, 'items': {'__all__': {'name': True}}} # No\n# According to Pydantic docs, for nested models it should be a dict.\n\n# Let's try to see if it's a Pydantic version issue or FastAPI's usage of it.\n# But the issue says \"introduced in 0.119.0\".\n\n# Let's look at how FastAPI handles 'include' before passing it to _model_dump.\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 30 | run_command | {
"command": "sed -n '220,240p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " if include is not None and not isinstance(include, (set, dict)):\n include = set(include)\n if exclude is not None and not isinstanfull{"status": "ok", "stdout": " if include is not None and not isinstance(include, (set, dict)):\n include = set(include)\n if exclude is not None and not isinstance(exclude, (set, dict)):\n exclude = set(exclude)\n if isinstance(obj, (BaseModel, may_v1.BaseModel)):\n # TODO: remove when deprecating Pydantic v1\n encoders: Dict[Any, Any] = {}\n if isinstance(obj, may_v1.BaseModel):\n encoders = getattr(obj.__config__, \"json_encoders\", {}) # type: ignore[attr-defined]\n if custom_encoder:\n encoders = {**encoders, **custom_encoder}\n obj_dict = _model_dump(\n obj,\n mode=\"json\",\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n exclude_defaults=exclude_defaults,\n )\n", "stderr": "", "exit_code": 0} |
| 31 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\ninclude = {'username': True, 'items': {'name': True}}\nprint(f\"Model dump: {user.model_dump(include=include)}\")\n\n# Try with a list of fields for the nested model\n# Pydantic v2: include={'items': {'name': True}} should work.\n# Let's try:\ninclude2 = {'username': True, 'items': {'name': True}}\nprint(f\"Model dump 2: {user.model_dump(include=include2)}\")\n\n# What if we use a set for the nested part?\n# Pydantic v2 doesn't support sets for nested include in the same way.\nPY\n"
} | {"status": "ok", "stdout": "Model dump: {'username': 'johndoe', 'items': []}\nModel dump 2: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": full{"status": "ok", "stdout": "Model dump: {'username': 'johndoe', 'items': []}\nModel dump 2: {'username': 'johndoe', 'items': []}\n", "stderr": "", "exit_code": 0} |
| 32 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Try this:\ninclude = {'username': True, 'items': {'name': True}}\n# Actually, for a list of models, Pydantic v2 expects the include for the elements of the list.\n# Let's try:\nprint(f\"Nested include: {user.model_dump(include={'items': {'name': True}})}\")\nPY\n"
} | {"status": "ok", "stdout": "Nested include: {'items': []}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Nested include: {'items': []}\n", "stderr": "", "exit_code": 0} |
| 33 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# In Pydantic v2, to include fields of a nested model that is in a list:\n# The include should be a dict where the key is the field name and the value is the include for that model.\n# But if it's a list of models, it should still work.\n\n# Let's try to see if it's because of the 'mode=\"json\"' in _model_dump.\n# In fastapi/encoders.py:\n# obj_dict = _model_dump(\n# obj,\n# mode=\"json\",\n# include=include,\n# ...\n# )\n\n# Let's try model_dump with mode=\"python\" (default)\nprint(f\"Mode python: {user.model_dump(include={'items': {'name': True}})}\")\nprint(f\"Mode json: {user.model_dump(include={'items': {'name': True}}, mode='json')}\")\nPY\n"
} | {"status": "ok", "stdout": "Mode python: {'items': []}\nMode json: {'items': []}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Mode python: {'items': []}\nMode json: {'items': []}\n", "stderr": "", "exit_code": 0} |
| 34 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Let's try to find the correct way to do nested include in Pydantic v2.\n# According to some sources, for a list of models, you might need to use a different syntax.\n# But actually, it should be:\nprint(f\"Try 1: {user.model_dump(include={'items': {'name': True}})}\")\n# Maybe:\nprint(f\"Try 2: {user.model_dump(include={'items': {'__all__': {'name': True}}})}\")\n# No, that's not it.\n\n# Let's try to see if it's because of the way FastAPI is passing the include.\n# In fastapi/encoders.py:\n# if include is not None and not isinstance(include, (set, dict)):\n# include = set(include)\nPY\n"
} | {"status": "ok", "stdout": "Try 1: {'items': []}\nTry 2: {'items': [{'name': 'item1'}, {'name': 'item2'}]}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Try 1: {'items': []}\nTry 2: {'items': [{'name': 'item1'}, {'name': 'item2'}]}\n", "stderr": "", "exit_code": 0} |
| 35 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Wait, Try 2 worked!\n# include={'items': {'__all__': {'name': True}}}\n# But this is not what users usually pass to FastAPI.\n# Users pass response_model_include={\"items\": {\"name\": True}}\n\n# Let's see if Pydantic v2 changed this.\n# Actually, if I use a set for the nested model:\n# include={'items': {'name'}} # No, that's not possible in a dict.\n\n# Let's try:\nprint(f\"Try 3: {user.model_dump(include={'items': {'name': True}})}\") # This was Try 1, returned []\nPY\n"
} | {"status": "ok", "stdout": "Try 3: {'items': []}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Try 3: {'items': []}\n", "stderr": "", "exit_code": 0} |
| 36 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Let's try to see if Pydantic v2 supports nested include for lists of models.\n# If I have a single model:\nclass SingleItem(BaseModel):\n name: str\n description: str\n\nclass SingleUser(BaseModel):\n username: str\n item: SingleItem\n\nuser_single = SingleUser(username=\"johndoe\", item=SingleItem(name=\"item1\", description=\"desc1\"))\nprint(f\"Single nested: {user_single.model_dump(include={'item': {'name': True}})}\")\nPY\n"
} | {"status": "ok", "stdout": "Single nested: {'item': {'name': 'item1'}}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Single nested: {'item': {'name': 'item1'}}\n", "stderr": "", "exit_code": 0} |
| 37 | run_command | {
"command": "python3 - <<'PY'\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# So it works for single models, but not for lists of models.\n# This is a Pydantic v2 behavior.\n# But FastAPI's jsonable_encoder is supposed to handle this.\n\n# Let's look at how jsonable_encoder handles lists.\n# In fastapi/encoders.py:\n# if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):\n# encoded_list = []\n# for item in obj:\n# encoded_list.append(\n# jsonable_encoder(\n# item,\n# include=include,\n# ...\n# )\n# )\n# return encoded_list\n\n# If we have a User model, jsonable_encoder(user, include={'items': {'name': True}})\n# 1. obj is User (BaseModel).\n# 2. It calls _model_dump(user, include={'items': {'name': True}}, ...).\n# 3. Pydantic's model_dump returns {'username': 'johndoe', 'items': []} because it's a list.\n# 4. Then it calls jsonable_encoder({'username': 'johndoe', 'items': []}, ...).\n# 5. This returns {'username': 'johndoe', 'items': []}.\n\n# The problem is that _model_dump is called with the full include, but Pydantic v2's model_dump\n# doesn't handle nested include for lists of models.\n\n# However, if we don't pass include to _model_dump, but instead let jsonable_encoder\n# handle it recursively...\n\n# Let's try to see what happens if we don't pass include to _model_dump.\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 38 | run_command | {
"command": "python3 - <<'PY'\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# If we use a dict instead of a BaseModel, it works because it goes to the dict handler.\nuser_dict = {\"username\": \"johndoe\", \"items\": [{\"name\": \"item1\", \"description\": \"desc1\"}, {\"name\": \"item2\", \"description\": \"desc2\"}]}\nprint(f\"Dict nested: {jsonable_encoder(user_dict, include={'username': True, 'items': {'name': True}})}\")\nPY\n"
} | {"status": "ok", "stdout": "Dict nested: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]full{"status": "ok", "stdout": "Dict nested: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}\n", "stderr": "", "exit_code": 0} |
| 39 | run_command | {
"command": "python3 - <<'PY'\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# Wait, if I use a dict, it still doesn't filter the nested items!\n# 'Dict nested: {'username': 'johndoe', 'items': [{'name': 'item1', 'description': 'desc1'}, {'name': 'item2', 'description': 'desc2'}]}'\n# It should have been [{'name': 'item1'}, {'name': 'item2'}]\n\n# Let's check the dict handler in fastapi/encoders.py:\n# for key, value in obj.items():\n# if (... and key in allowed_keys):\n# ...\n# encoded_value = jsonable_encoder(\n# value,\n# by_alias=by_alias,\n# exclude_unset=exclude_unset,\n# exclude_none=exclude_none,\n# custom_encoder=custom_encoder,\n# sqlalchemy_safe=sqlalchemy_safe,\n# )\n# encoded_dict[encoded_key] = encoded_value\n\n# IT DOES NOT PASS 'include' and 'exclude' to the recursive call for dict values!\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0} |
| 40 | run_command | {
"command": "sed -n '280,310p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " for key, value in obj.items():\n if (\n (\n not sqlalchemy_safe\n or (not isinstance(key, str))\n or (not key.startswith(\"_sa\"))\full{"status": "ok", "stdout": " for key, value in obj.items():\n if (\n (\n not sqlalchemy_safe\n or (not isinstance(key, str))\n or (not key.startswith(\"_sa\"))\n )\n and (value is not None or not exclude_none)\n and key in allowed_keys\n ):\n encoded_key = jsonable_encoder(\n key,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n encoded_value = jsonable_encoder(\n value,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n encoded_dict[encoded_key] = encoded_value\n return encoded_dict\n if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):\n encoded_list = []\n for item in obj:\n", "stderr": "", "exit_code": 0} |
| 41 | run_command | {
"command": "python3 - <<'PY'\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Item(BaseModel):\n name: str\n description: str\n\nclass User(BaseModel):\n username: str\n items: List[Item]\n\nuser = User(username=\"johndoe\", items=[Item(name=\"item1\", description=\"desc1\"), Item(name=\"item2\", description=\"desc2\")])\n\n# If we want to fix this, we need to pass the correct 'include' and 'exclude' to the recursive calls.\n# For a dict, if include is {'username': True, 'items': {'name': True}},\n# when we are at 'items', the new include should be {'name': True}.\n\n# Let's see how to extract the nested include.\ndef get_nested_include(include, key):\n if include is None:\n return None\n if isinstance(include, set):\n return None # or something else?\n if isinstance(include, dict):\n val = include.get(key)\n if val is True:\n return None # include all\n return val\n return None\n\n# Let's test this logic.\ninclude = {'username': True, 'items': {'name': True}}\nprint(f\"Nested for username: {get_nested_include(include, 'username')}\")\nprint(f\"Nested for items: {get_nested_include(include, 'items')}\")\nPY\n"
} | {"status": "ok", "stdout": "Nested for username: None\nNested for items: {'name': True}\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "Nested for username: None\nNested for items: {'name': True}\n", "stderr": "", "exit_code": 0} |
| 42 | run_command | {
"command": "sed -n '260,266p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,full{"status": "ok", "stdout": " exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n if isinstance(obj, Enum):\n return obj.value\n", "stderr": "", "exit_code": 0} |
| 43 | run_command | {
"command": "sed -n '240,266p' fastapi/encoders.py"
} | {"status": "ok", "stdout": " )\n if \"__root__\" in obj_dict:\n obj_dict = obj_dict[\"__root__\"]\n return jsonable_encoder(\n obj_dict,\n exclude_none=exclude_full{"status": "ok", "stdout": " )\n if \"__root__\" in obj_dict:\n obj_dict = obj_dict[\"__root__\"]\n return jsonable_encoder(\n obj_dict,\n exclude_none=exclude_none,\n exclude_defaults=exclude_defaults,\n # TODO: remove when deprecating Pydantic v1\n custom_encoder=encoders,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n if dataclasses.is_dataclass(obj):\n assert not isinstance(obj, type)\n obj_dict = dataclasses.asdict(obj)\n return jsonable_encoder(\n obj_dict,\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none,\n custom_encoder=custom_encoder,\n sqlalchemy_safe=sqlalchemy_safe,\n )\n if isinstance(obj, Enum):\n return obj.value\n", "stderr": "", "exit_code": 0} |