python-starlette fails to build with Python 3.14.0a5. __________________________ test_wsgi_post[asyncio] ____________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='asyncio', backend_options={}) def test_wsgi_post(test_client_factory: TestClientFactory) -> None: app = WSGIMiddleware(echo_body) client = test_client_factory(app) response = client.post("/", json={"example": 123}) assert response.status_code == 200 > assert response.text == '{"example":123}' E assert '{"example": 123}' == '{"example":123}' E E - {"example":123} E + {"example": 123} E ? + tests/middleware/test_wsgi.py:81: AssertionError _____________________________ test_wsgi_post[trio] _____________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='trio', backend_options={}) def test_wsgi_post(test_client_factory: TestClientFactory) -> None: app = WSGIMiddleware(echo_body) client = test_client_factory(app) response = client.post("/", json={"example": 123}) assert response.status_code == 200 > assert response.text == '{"example":123}' E assert '{"example": 123}' == '{"example":123}' E E - {"example":123} E + {"example": 123} E ? + tests/middleware/test_wsgi.py:81: AssertionError __________________________ test_request_body[asyncio] __________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='asyncio', backend_options={}) def test_request_body(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = await request.body() response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"body": ""} response = client.post("/", json={"a": "123"}) > assert response.json() == {"body": '{"a":"123"}'} E assert {'body': '{"a": "123"}'} == {'body': '{"a":"123"}'} E E Differing items: E {'body': '{"a": "123"}'} != {'body': '{"a":"123"}'} E E Full diff: E { E - 'body': '{"a":"123"}',... E E ...Full output truncated (3 lines hidden), use '-vv' to show tests/test_requests.py:95: AssertionError _________________________ test_request_stream[asyncio] _________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='asyncio', backend_options={}) def test_request_stream(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = b"" async for chunk in request.stream(): body += chunk response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"body": ""} response = client.post("/", json={"a": "123"}) > assert response.json() == {"body": '{"a":"123"}'} E assert {'body': '{"a": "123"}'} == {'body': '{"a":"123"}'} E E Differing items: E {'body': '{"a": "123"}'} != {'body': '{"a":"123"}'} E E Full diff: E { E - 'body': '{"a":"123"}',... E E ...Full output truncated (3 lines hidden), use '-vv' to show tests/test_requests.py:116: AssertionError ___________________________ test_request_body[trio] ____________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='trio', backend_options={}) def test_request_body(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = await request.body() response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"body": ""} response = client.post("/", json={"a": "123"}) > assert response.json() == {"body": '{"a":"123"}'} E assert {'body': '{"a": "123"}'} == {'body': '{"a":"123"}'} E E Differing items: E {'body': '{"a": "123"}'} != {'body': '{"a":"123"}'} E E Full diff: E { E - 'body': '{"a":"123"}',... E E ...Full output truncated (3 lines hidden), use '-vv' to show tests/test_requests.py:95: AssertionError __________________________ test_request_stream[trio] ___________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='trio', backend_options={}) def test_request_stream(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = b"" async for chunk in request.stream(): body += chunk response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"body": ""} response = client.post("/", json={"a": "123"}) > assert response.json() == {"body": '{"a":"123"}'} E assert {'body': '{"a": "123"}'} == {'body': '{"a":"123"}'} E E Differing items: E {'body': '{"a": "123"}'} != {'body': '{"a":"123"}'} E E Full diff: E { E - 'body': '{"a":"123"}',... E E ...Full output truncated (3 lines hidden), use '-vv' to show https://docs.python.org/3.14/whatsnew/3.14.html For the build logs, see: https://copr-be.cloud.fedoraproject.org/results/@python/python3.14/fedora-rawhide-x86_64/08716724-python-starlette/ For all our attempts to build python-starlette with Python 3.14, see: https://copr.fedorainfracloud.org/coprs/g/python/python3.14/package/python-starlette/ Testing and mass rebuild of packages is happening in copr. You can follow these instructions to test locally in mock if your package builds with Python 3.14: https://copr.fedorainfracloud.org/coprs/g/python/python3.14/ Let us know here if you have any questions. Python 3.14 is planned to be included in Fedora 43. To make that update smoother, we're building Fedora packages with all pre-releases of Python 3.14. A build failure prevents us from testing all dependent packages (transitive [Build]Requires), so if this package is required a lot, it's important for us to get it fixed soon. We'd appreciate help from the people who know this package best, but if you don't want to work on this now, let us know so we can try to work around it on our side.
A minor adjustment in the tests was required for httpx 0.28.x. We were carrying a patch to revert that change for compatibility with httpx<0.28 until python-httpx was updated in Rawhide; once that happened, I dropped the patch[1]. The Rawhide branch of python-starlette therefore now requires httpx >= 0.28 for testing. This will work correctly again once the Python 3.14 COPR has a current build of python-httpx[2] to match Rawhide. Since you handled the last COPR build of python-httpx[3] by spec/SRPM upload, and the package in COPR doesn’t have dist-git set up as a default source, I’ll refrain from rebuilding it myself and just assign this back to you. Please do let me know if there’s anything I can do to help, though. [1] https://src.fedoraproject.org/rpms/python-starlette/c/e0311d228e27b446779bdda8092206f33149d647?branch=rawhide [2] https://copr.fedorainfracloud.org/coprs/g/python/python3.14/package/python-httpx/ [3] https://copr.fedorainfracloud.org/coprs/g/python/python3.14/build/8647528/
Thank you! We can't yet build httpx with tests, because of missing python-uvicorn -> python-uvloop, but I sent a build without them, which succeeded, and so succeeded python-starlette. This is now solved.