]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✅ Test order for the submitted byte Files (#14828)
authorValentyn <valentin.druzhinin@gmail.com>
Tue, 10 Feb 2026 11:46:48 +0000 (06:46 -0500)
committerGitHub <noreply@github.com>
Tue, 10 Feb 2026 11:46:48 +0000 (11:46 +0000)
Co-authored-by: Valentyn Druzhynin <v.druzhynin@zakaz.global>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
tests/test_list_bytes_file_order_preserved_issue_14811.py [new file with mode: 0644]

diff --git a/tests/test_list_bytes_file_order_preserved_issue_14811.py b/tests/test_list_bytes_file_order_preserved_issue_14811.py
new file mode 100644 (file)
index 0000000..399235b
--- /dev/null
@@ -0,0 +1,46 @@
+"""
+Regression test: preserve order when using list[bytes] + File()
+See https://github.com/fastapi/fastapi/discussions/14811
+Related: PR #3372
+"""
+
+from typing import Annotated
+
+import anyio
+import pytest
+from fastapi import FastAPI, File
+from fastapi.testclient import TestClient
+from starlette.datastructures import UploadFile as StarletteUploadFile
+
+
+def test_list_bytes_file_preserves_order(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    app = FastAPI()
+
+    @app.post("/upload")
+    async def upload(files: Annotated[list[bytes], File()]):
+        # return something that makes order obvious
+        return [b[0] for b in files]
+
+    original_read = StarletteUploadFile.read
+
+    async def patched_read(self: StarletteUploadFile, size: int = -1) -> bytes:
+        # Make the FIRST file slower *deterministically*
+        if self.filename == "slow.txt":
+            await anyio.sleep(0.05)
+        return await original_read(self, size)
+
+    monkeypatch.setattr(StarletteUploadFile, "read", patched_read)
+
+    client = TestClient(app)
+
+    files = [
+        ("files", ("slow.txt", b"A" * 10, "text/plain")),
+        ("files", ("fast.txt", b"B" * 10, "text/plain")),
+    ]
+    r = client.post("/upload", files=files)
+    assert r.status_code == 200, r.text
+
+    # Must preserve request order: slow first, fast second
+    assert r.json() == [ord("A"), ord("B")]