← baseline_full_v2

fastapi_14356

failed NO_PATCH NO_PATCH UNSUBMITTED empty_patch(None) · None tool calls · 0 s · fastapi/fastapi

Task input

🐛 Fix parsing extra non-body parameter list

Currently if we declare Query or Header parameters as model with `extra="allow"` and then pass extra parameter with multiple values, only last value of such parameter will be passed to model validator:

```py
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel

app = FastAPI()


class Model(BaseModel):
    param: str

    model_config = {"extra": "allow"}


@app.get("/")
async def model_with_extra(data: Model = Query()):
    return data


def test_pass_extra_list():
    client = TestClient(app)
    resp = client.get(
        "/",
        params={
            "param": "123",
            "param2": ["456", "789"],  # Pass a list of values as extra parameter
        },
    )
    assert resp.status_code == 200
    assert resp.json() == {
        "param": "123",
        "param2": ["456", "789"],
    }

# AssertionError: assert
# {'param': '123', 'param2': '789'} == {'param': '123', 'param2': ['456', '789']}
```

The reason is the same as with Form parameters. See #14303
There is also a note about implementation described in #14303. It's also relevant to this PR.

**As for Cookies:**
As far as I understand the spec, you can't pass multiple Cookie parameters with the same name (only last value will be used). The only way to pass a list of values is to pass them comma-separated, but it's not currently supported by Starlette

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Test output

show
F
=================================== FAILURES ===================================
__________________________ test_query_pass_extra_list __________________________

    def test_query_pass_extra_list():
        client = TestClient(app)
        resp = client.get(
            "/query",
            params={
                "param": "123",
                "param2": ["456", "789"],  # Pass a list of values as extra parameter
            },
        )
        assert resp.status_code == 200
>       assert resp.json() == {
            "param": "123",
            "param2": ["456", "789"],
        }
E       AssertionError: assert {'param': '12...aram2': '789'} == {'param': '12...'456', '789']}
E         
E         Omitting 1 identical items, use -vv to show
E         Differing items:
E         {'param2': '789'} != {'param2': ['456', '789']}
E         Use -v to get more diff

tests/test_query_cookie_header_model_extra_params.py:45: AssertionError
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.50.0-py3-none-any/starlette/testclient.py:45
  /Users/jp/repos/kaggle-gemini-coding-agent-post-training/.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
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 failed, 1 warning in 0.67s