failed WRONG_FIX UNSUBMITTED wrong_fix_unsubmitted(timeout) · 30 tool calls · 0 s · fastapi/fastapi
♻️ Do not accept underscore headers when using `convert_underscores=True` (the default) ## Pull Request <!-- Please start with a GitHub Discussion. Once a team member asks you to open a PR, create it and link the discussion here. Obvious typo fixes can be made in a PR without starting a discussion. --> Discussion: <!-- Link to the GitHub Discussion --> ## Description ♻️ Do not accept underscore headers when using `convert_underscores=True` (the default) This means it would only accept header names separated with hyphens by default, and to accept header names separated with underscores, an app would need to explicitly set `convert_underscores=False`. <!-- Write the description of your PR here --> ## AI Disclaimer <!-- If using AI, write here the prompt and model used --> <details> <summary>AI transcript</summary> <!-- Paste here the entire AI transcript --> </details> ## Checklist - [ ] This PR is an obvious typo fix, or it links to a GitHub Discussion for the proposed code change. - [ ] I added tests for the change. - [ ] The new or updated tests fail on the main branch and pass on this PR. - [ ] Coverage stays at 100%. - [ ] The documentation explains the change if needed.
| # | Tool | Arguments | Result |
|---|---|---|---|
| No trace captured. | |||
diff --git a/repro.py b/repro.py
new file mode 100644
index 000000000..861af14a3
--- /dev/null
+++ b/repro.py
@@ -0,0 +1,40 @@
+
+from fastapi import FastAPI, Header
+from fastapi.testclient import TestClient
+import pytest
+
+app = FastAPI()
+
+@app.get("/items")
+async def read_items(user_agent: str = Header(default="testclient")):
+ return {"User-Agent": user_agent}
+
+@app.get("/items_underscore")
+async def read_items_underscore(user_agent_name: str = Header(default="testclient")):
+ return {"User-Agent": user_agent_name}
+
+client = TestClient(app)
+
+def test_header_hyphen():
+ # Should work: user-agent-name -> user_agent_name
+ response = client.get("/items_underscore", headers={"user-agent-name": "fastapi-test"})
+ assert response.status_code == 200
+ assert response.json() == {"User-Agent": "fastapi-test"}
+
+def test_header_underscore_default():
+ # Should NOT work by default: user_agent_name -> user_agent_name
+ response = client.get("/items_underscore", headers={"user_agent_name": "fastapi-test"})
+ # If the change is implemented, this should return the default value
+ assert response.json() == {"User-Agent": "testclient"}
+
+def test_header_underscore_disabled():
+ # Now test with convert_underscores=False
+ app_disabled = FastAPI()
+ @app_disabled.get("/items")
+ async def read_items_disabled(user_agent_name: str = Header(default="testclient", convert_underscores=False)):
+ return {"User-Agent": user_agent_name}
+
+ client_disabled = TestClient(app_disabled)
+ response = client_disabled.get("/items", headers={"user_agent_name": "fastapi-test"})
+ assert response.status_code == 200
+ assert response.json() == {"User-Agent": "fastapi-test"}
....F
=================================== FAILURES ===================================
_____ test_header_model_prefers_hyphenated_header_with_convert_underscores _____
def test_header_model_prefers_hyphenated_header_with_convert_underscores():
client = TestClient(app)
resp = client.get(
"/header-requires-hyphen",
headers=[
("x-user-id", "hyphenated-value"),
("x_user_id", "underscore-value"),
],
)
assert resp.status_code == 200
> assert resp.json() == {"x_user_id": "hyphenated-value"}
E AssertionError: assert {'x_user_id':...rscore-value'} == {'x_user_id':...enated-value'}
E
E Differing items:
E {'x_user_id': 'underscore-value'} != {'x_user_id': 'hyphenated-value'}
E Use -v to get more diff
tests/test_query_cookie_header_model_extra_params.py:115: AssertionError
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-1.6.0-py3-none-any/starlette/testclient.py:53
/Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-1.6.0-py3-none-any/starlette/testclient.py:53: 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, 4 passed, 1 warning in 0.57s