Fix Optional[Literal] Form field handling when value is None#14766
Fix Optional[Literal] Form field handling when value is None#14766developreiloyo wants to merge 2 commits intofastapi:masterfrom
Conversation
CodSpeed Performance ReportMerging this PR will not alter performanceComparing Summary
Footnotes |
YuriiMotov
left a comment
There was a problem hiding this comment.
@developreiloyo, thanks for your interest and efforts!
There is currently issue with passing empty str to optional Form field that has non-None default value.
The problem is that it's not related to Literal - it will fail with any other type as well.
So, it should be solved in different way
| def test_optional_literal_form_none(): | ||
| """Test that omitting an optional form field returns None""" | ||
| app = FastAPI() | ||
|
|
||
| @app.post("/") | ||
| async def read_main(attribute: Annotated[Optional[Literal["abc", "def"]], Form()]): | ||
| return {"attribute": attribute} | ||
|
|
||
| client = TestClient(app) | ||
|
|
||
| # FIXED: Use empty data instead of {"attribute": None} | ||
| response = client.post("/", data={}) | ||
| assert response.status_code == 200 | ||
| assert response.json() == {"attribute": None} |
There was a problem hiding this comment.
This test is incorrect..
The attribute parameter is nullable, but still required. So, not passing it should result in 422 error response
| def test_optional_literal_form_empty_string(): | ||
| """Test that empty string is treated as None for optional Form fields""" | ||
| app = FastAPI() | ||
|
|
||
| @app.post("/") | ||
| async def read_main(attribute: Annotated[Optional[Literal["abc", "def"]], Form()]): | ||
| return {"attribute": attribute} | ||
|
|
||
| client = TestClient(app) | ||
|
|
||
| # Empty string is treated as "not provided" for optional Form fields | ||
| # This is consistent with FastAPI's behavior for Form data | ||
| response = client.post("/", data={"attribute": ""}) | ||
| assert response.status_code == 200 | ||
| assert response.json() == {"attribute": None} |
There was a problem hiding this comment.
This is a known issue, and it fails for Optional[str] as well.
Just change the type annotation to Optional[str] and run this test on master branch - you will see the same error
🐛 Bug
Optional[Literal[...]]form fields were returning422 Unprocessable Entitywhen the submitted value was
None, even though the field was optional.This behavior was inconsistent with other optional form fields such as
Optional[str]orOptional[List[str]].✅ Fix
Nonevalues forOptional[Literal]form fields🧪 Tests