Source: starlette Version: 0.38.2-1 Severity: normal User: debian-pyt...@lists.debian.org Usertags: python3.13 Forwarded: https://github.com/encode/starlette/pull/2662
This package failed build from source when test-built against a version of python3-defaults that includes 3.13 as a supported version. To reproduce this issue, build against python3-defaults (python3-all-dev etc.) from Debian experimental. What's new in Python 3.13: https://docs.python.org/3.13/whatsnew/3.13.html Log snippet: tests/test_websockets.py ...................................... [100%] =================================== FAILURES =================================== ___________________________ test_debug_html[asyncio] ___________________________ test_client_factory = functools.partial(<class 'starlette.testclient.TestClient'>, backend='asyncio', backend_options={}) def test_debug_html(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: raise RuntimeError("Something went wrong") app = ServerErrorMiddleware(app, debug=True) client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/", headers={"Accept": "text/html, */*"}) assert response.status_code == 500 > assert response.headers["content-type"].startswith("text/html") tests/middleware/test_errors.py:51: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Headers({}), key = 'content-type' def __getitem__(self, key: str) -> str: """ Return a single header value. If there are multiple headers with the same key, then we concatenate them with commas. See: https://tools.ietf.org/html/rfc7230#section-3.2.2 """ normalized_key = key.lower().encode(self.encoding) items = [ header_value.decode(self.encoding) for _, header_key, header_value in self._list if header_key == normalized_key ] if items: return ", ".join(items) > raise KeyError(key) E KeyError: 'content-type' /usr/lib/python3/dist-packages/httpx/_models.py:228: KeyError ___________________ test_https_redirect_middleware[asyncio] ____________________ cls = <class '_pytest.runner.CallInfo'> func = <function call_and_report.<locals>.<lambda> at 0xffffa1607600> when = 'call' reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>) @classmethod def from_call( cls, func: Callable[[], TResult], when: Literal["collect", "setup", "call", "teardown"], reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None, ) -> CallInfo[TResult]: """Call func, wrapping the result in a CallInfo. :param func: The function to call. Called without arguments. :type func: Callable[[], _pytest.runner.TResult] :param when: The phase in which the function is called. :param reraise: Exception or exceptions that shall propagate if raised by the function, instead of being wrapped in the CallInfo. """ excinfo = None start = timing.time() precise_start = timing.perf_counter() try: > result: TResult | None = func() /usr/lib/python3/dist-packages/_pytest/runner.py:341: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/_pytest/runner.py:242: in <lambda> lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise /usr/lib/python3/dist-packages/pluggy/_hooks.py:513: in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) /usr/lib/python3/dist-packages/pluggy/_manager.py:120: in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) /usr/lib/python3/dist-packages/_pytest/threadexception.py:92: in pytest_runtest_call yield from thread_exception_runtest_hook() /usr/lib/python3/dist-packages/_pytest/threadexception.py:68: in thread_exception_runtest_hook yield /usr/lib/python3/dist-packages/_pytest/unraisableexception.py:95: in pytest_runtest_call yield from unraisable_exception_runtest_hook() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def unraisable_exception_runtest_hook() -> Generator[None]: with catch_unraisable_exception() as cm: try: yield finally: if cm.unraisable: if cm.unraisable.err_msg is not None: err_msg = cm.unraisable.err_msg else: err_msg = "Exception ignored in" msg = f"{err_msg}: {cm.unraisable.object!r}\n\n" msg += "".join( traceback.format_exception( cm.unraisable.exc_type, cm.unraisable.exc_value, cm.unraisable.exc_traceback, ) ) > warnings.warn(pytest.PytestUnraisableExceptionWarning(msg)) E pytest.PytestUnraisableExceptionWarning: Exception ignored in: <gzip on 0xffffa16cc190> E E Traceback (most recent call last): E File "/usr/lib/python3.13/gzip.py", line 359, in close E fileobj.write(self.compress.flush()) E ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ E ValueError: I/O operation on closed file. /usr/lib/python3/dist-packages/_pytest/unraisableexception.py:85: PytestUnraisableExceptionWarning =================== 2 failed, 442 passed, 1 xfailed in 5.72s =================== E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_starlette/build; python3.13 -m pytest tests I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_starlette/build; python3.12 -m pytest tests ============================= test session starts ============================== platform linux -- Python 3.12.6, pytest-8.3.3, pluggy-1.5.0 rootdir: /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_starlette/build configfile: pyproject.toml plugins: typeguard-4.3.0, anyio-4.4.0 collected 445 items tests/middleware/test_base.py .....x.................. [ 5%] tests/middleware/test_cors.py ............... [ 8%] tests/middleware/test_errors.py ...... [ 10%] tests/middleware/test_gzip.py ..... [ 11%] tests/middleware/test_https_redirect.py . [ 11%] tests/middleware/test_middleware.py .. [ 11%] tests/middleware/test_session.py ....... [ 13%] tests/middleware/test_trusted_host.py ... [ 14%] tests/middleware/test_wsgi.py ...... [ 15%] tests/test__utils.py ...... [ 16%] tests/test_applications.py .......................... [ 22%] tests/test_authentication.py ...... [ 24%] tests/test_background.py .... [ 24%] tests/test_concurrency.py ... [ 25%] tests/test_config.py ..... [ 26%] tests/test_convertors.py ... [ 27%] tests/test_datastructures.py ........................ [ 32%] tests/test_endpoints.py .......... [ 35%] tests/test_exceptions.py ............. [ 37%] tests/test_formparsers.py ................................... [ 45%] tests/test_requests.py .......................................... [ 55%] tests/test_responses.py .................................... [ 63%] tests/test_routing.py .................................................. [ 74%] ...... [ 75%] tests/test_schemas.py .. [ 76%] tests/test_staticfiles.py ............................. [ 82%] tests/test_status.py .. [ 83%] tests/test_templates.py ............... [ 86%] tests/test_testclient.py ..................... [ 91%] tests/test_websockets.py ...................................... [100%] ======================== 444 passed, 1 xfailed in 5.53s ======================== dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.13 3.12" returned exit code 13 make: *** [debian/rules:5: build] Error 25 dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2 -------------------------------------------------------------------------------- Build finished at 2024-09-19T13:45:33Z If required, the full build log is available here (for the next 30 days): https://debusine.debian.net/artifact/794363/ This bug has been filed at "normal" severity, as we haven't started the transition to add 3.13 as a supported version, yet. This will be raised to RC as soon as that happens, hopefully well before trixie. Thanks, Stefano