Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-starlette for openSUSE:Factory checked in at 2022-12-13 18:56:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-starlette (Old) and /work/SRC/openSUSE:Factory/.python-starlette.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-starlette" Tue Dec 13 18:56:46 2022 rev:14 rq:1042664 version:0.23.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-starlette/python-starlette.changes 2022-11-28 11:07:34.751894604 +0100 +++ /work/SRC/openSUSE:Factory/.python-starlette.new.1835/python-starlette.changes 2022-12-13 18:57:08.675740353 +0100 @@ -1,0 +2,19 @@ +Tue Dec 13 08:27:49 UTC 2022 - David Anes <david.a...@suse.com> + +- Update to 0.21.3 + * Fixed + - Only stop receiving stream on body_stream if body is empty on i + the BaseHTTPMiddleware. + +- Update to 0.21.0 + * Added + - Add headers parameter to the TestClient. + * Deprecated + - Deprecate Starlette and Router decorators. + * Fixed + - Fix bug on FloatConvertor regex. + +- Fix test package by adding 'exceptiongroup' python module as a + build dependency. + +------------------------------------------------------------------- Old: ---- starlette-0.22.0.tar.gz New: ---- starlette-0.23.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-starlette.spec ++++++ --- /var/tmp/diff_new_pack.PFOqhf/_old 2022-12-13 18:57:10.415749639 +0100 +++ /var/tmp/diff_new_pack.PFOqhf/_new 2022-12-13 18:57:10.419749661 +0100 @@ -27,7 +27,7 @@ %{?!python_module:%define python_module() python3-%{**}} %define skip_python2 1 Name: python-starlette%{psuffix} -Version: 0.22.0 +Version: 0.23.1 Release: 0 Summary: Lightweight ASGI framework/toolkit License: BSD-3-Clause @@ -53,6 +53,7 @@ BuildRequires: %{python_module aiofiles} BuildRequires: %{python_module aiosqlite} BuildRequires: %{python_module databases} +BuildRequires: %{python_module exceptiongroup} BuildRequires: %{python_module graphene} BuildRequires: %{python_module pytest-asyncio} BuildRequires: %{python_module pytest} ++++++ starlette-0.22.0.tar.gz -> starlette-0.23.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/docs/release-notes.md new/starlette-0.23.1/docs/release-notes.md --- old/starlette-0.22.0/docs/release-notes.md 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/docs/release-notes.md 2022-12-09 15:45:37.000000000 +0100 @@ -1,3 +1,23 @@ +## 0.23.1 + +December 9, 2022 + +### Fixed +* Only stop receiving stream on `body_stream` if body is empty on the `BaseHTTPMiddleware` [#1940](https://github.com/encode/starlette/pull/1940). + +## 0.23.0 + +December 5, 2022 + +### Added +* Add `headers` parameter to the `TestClient` [#1966](https://github.com/encode/starlette/pull/1966). + +### Deprecated +* Deprecate `Starlette` and `Router` decorators [#1897](https://github.com/encode/starlette/pull/1897). + +### Fixed +* Fix bug on `FloatConvertor` regex [#1973](https://github.com/encode/starlette/pull/1973). + ## 0.22.0 November 17, 2022 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/requirements.txt new/starlette-0.23.1/requirements.txt --- old/starlette-0.22.0/requirements.txt 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/requirements.txt 2022-12-09 15:45:37.000000000 +0100 @@ -3,21 +3,21 @@ # Testing autoflake==1.5.3 -black==22.8.0 +black==22.10.0 coverage==6.5.0 flake8==3.9.2 importlib-metadata==4.13.0 isort==5.10.1 -mypy==0.971 +mypy==0.991 typing_extensions==4.4.0 types-contextvars==2.4.7 -types-PyYAML==6.0.12 +types-PyYAML==6.0.12.2 types-dataclasses==0.6.6 pytest==7.2.0 trio==0.21.0 # Documentation -mkdocs==1.4.0 +mkdocs==1.4.2 mkdocs-material==8.5.7 mkautodoc==0.2.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/starlette/__init__.py new/starlette-0.23.1/starlette/__init__.py --- old/starlette-0.22.0/starlette/__init__.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/starlette/__init__.py 2022-12-09 15:45:37.000000000 +0100 @@ -1 +1 @@ -__version__ = "0.22.0" +__version__ = "0.23.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/starlette/applications.py new/starlette-0.23.1/starlette/applications.py --- old/starlette-0.22.0/starlette/applications.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/starlette/applications.py 2022-12-09 15:45:37.000000000 +0100 @@ -1,4 +1,5 @@ import typing +import warnings from starlette.datastructures import State, URLPath from starlette.middleware import Middleware @@ -123,43 +124,17 @@ scope["app"] = self await self.middleware_stack(scope, receive, send) - # The following usages are now discouraged in favour of configuration - # during Starlette.__init__(...) def on_event(self, event_type: str) -> typing.Callable: # pragma: nocover return self.router.on_event(event_type) def mount( self, path: str, app: ASGIApp, name: typing.Optional[str] = None ) -> None: # pragma: nocover - """ - We no longer document this API, and its usage is discouraged. - Instead you should use the following approach: - - routes = [ - Mount(path, ...), - ... - ] - - app = Starlette(routes=routes) - """ - self.router.mount(path, app=app, name=name) def host( self, host: str, app: ASGIApp, name: typing.Optional[str] = None ) -> None: # pragma: no cover - """ - We no longer document this API, and its usage is discouraged. - Instead you should use the following approach: - - routes = [ - Host(path, ...), - ... - ] - - app = Starlette(routes=routes) - """ - self.router.host(host, app=app, name=name) def add_middleware( @@ -200,7 +175,13 @@ def exception_handler( self, exc_class_or_status_code: typing.Union[int, typing.Type[Exception]] - ) -> typing.Callable: # pragma: nocover + ) -> typing.Callable: + warnings.warn( + "The `exception_handler` decorator is deprecated, and will be removed in version 1.0.0. " # noqa: E501 + "Refer to https://www.starlette.io/exceptions/ for the recommended approach.", # noqa: E501 + DeprecationWarning, + ) + def decorator(func: typing.Callable) -> typing.Callable: self.add_exception_handler(exc_class_or_status_code, func) return func @@ -213,18 +194,19 @@ methods: typing.Optional[typing.List[str]] = None, name: typing.Optional[str] = None, include_in_schema: bool = True, - ) -> typing.Callable: # pragma: nocover + ) -> typing.Callable: """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: - routes = [ - Route(path, endpoint=..., ...), - ... - ] - - app = Starlette(routes=routes) + >>> routes = [Route(path, endpoint=...), ...] + >>> app = Starlette(routes=routes) """ + warnings.warn( + "The `route` decorator is deprecated, and will be removed in version 1.0.0. " # noqa: E501 + "Refer to https://www.starlette.io/routing/ for the recommended approach.", # noqa: E501 + DeprecationWarning, + ) def decorator(func: typing.Callable) -> typing.Callable: self.router.add_route( @@ -240,18 +222,19 @@ def websocket_route( self, path: str, name: typing.Optional[str] = None - ) -> typing.Callable: # pragma: nocover + ) -> typing.Callable: """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: - routes = [ - WebSocketRoute(path, endpoint=..., ...), - ... - ] - - app = Starlette(routes=routes) + >>> routes = [WebSocketRoute(path, endpoint=...), ...] + >>> app = Starlette(routes=routes) """ + warnings.warn( + "The `websocket_route` decorator is deprecated, and will be removed in version 1.0.0. " # noqa: E501 + "Refer to https://www.starlette.io/routing/#websocket-routing for the recommended approach.", # noqa: E501 + DeprecationWarning, + ) def decorator(func: typing.Callable) -> typing.Callable: self.router.add_websocket_route(path, func, name=name) @@ -259,19 +242,19 @@ return decorator - def middleware(self, middleware_type: str) -> typing.Callable: # pragma: nocover + def middleware(self, middleware_type: str) -> typing.Callable: """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: - middleware = [ - Middleware(...), - ... - ] - - app = Starlette(middleware=middleware) + >>> middleware = [Middleware(...), ...] + >>> app = Starlette(middleware=middleware) """ - + warnings.warn( + "The `middleware` decorator is deprecated, and will be removed in version 1.0.0. " # noqa: E501 + "Refer to https://www.starlette.io/middleware/#using-middleware for recommended approach.", # noqa: E501 + DeprecationWarning, + ) assert ( middleware_type == "http" ), 'Currently only middleware("http") is supported.' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/starlette/convertors.py new/starlette-0.23.1/starlette/convertors.py --- old/starlette-0.22.0/starlette/convertors.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/starlette/convertors.py 2022-12-09 15:45:37.000000000 +0100 @@ -51,7 +51,7 @@ class FloatConvertor(Convertor): - regex = "[0-9]+(.[0-9]+)?" + regex = r"[0-9]+(\.[0-9]+)?" def convert(self, value: str) -> float: return float(value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/starlette/middleware/base.py new/starlette-0.23.1/starlette/middleware/base.py --- old/starlette-0.22.0/starlette/middleware/base.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/starlette/middleware/base.py 2022-12-09 15:45:37.000000000 +0100 @@ -89,8 +89,6 @@ body = message.get("body", b"") if body: yield body - if not message.get("more_body", False): - break if app_exc is not None: raise app_exc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/starlette/routing.py new/starlette-0.23.1/starlette/routing.py --- old/starlette-0.22.0/starlette/routing.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/starlette/routing.py 2022-12-09 15:45:37.000000000 +0100 @@ -737,41 +737,15 @@ def __eq__(self, other: typing.Any) -> bool: return isinstance(other, Router) and self.routes == other.routes - # The following usages are now discouraged in favour of configuration - # Â during Router.__init__(...) def mount( self, path: str, app: ASGIApp, name: typing.Optional[str] = None ) -> None: # pragma: nocover - """ - We no longer document this API, and its usage is discouraged. - Instead you should use the following approach: - - routes = [ - Mount(path, ...), - ... - ] - - app = Starlette(routes=routes) - """ - route = Mount(path, app=app, name=name) self.routes.append(route) def host( self, host: str, app: ASGIApp, name: typing.Optional[str] = None ) -> None: # pragma: no cover - """ - We no longer document this API, and its usage is discouraged. - Instead you should use the following approach: - - routes = [ - Host(path, ...), - ... - ] - - app = Starlette(routes=routes) - """ - route = Host(host, app=app, name=name) self.routes.append(route) @@ -804,18 +778,19 @@ methods: typing.Optional[typing.List[str]] = None, name: typing.Optional[str] = None, include_in_schema: bool = True, - ) -> typing.Callable: # pragma: nocover + ) -> typing.Callable: """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: - routes = [ - Route(path, endpoint=..., ...), - ... - ] - - app = Starlette(routes=routes) + >>> routes = [Route(path, endpoint=...), ...] + >>> app = Starlette(routes=routes) """ + warnings.warn( + "The `route` decorator is deprecated, and will be removed in version 1.0.0." + "Refer to https://www.starlette.io/routing/#http-routing for the recommended approach.", # noqa: E501 + DeprecationWarning, + ) def decorator(func: typing.Callable) -> typing.Callable: self.add_route( @@ -831,18 +806,19 @@ def websocket_route( self, path: str, name: typing.Optional[str] = None - ) -> typing.Callable: # pragma: nocover + ) -> typing.Callable: """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: - routes = [ - WebSocketRoute(path, endpoint=..., ...), - ... - ] - - app = Starlette(routes=routes) + >>> routes = [WebSocketRoute(path, endpoint=...), ...] + >>> app = Starlette(routes=routes) """ + warnings.warn( + "The `websocket_route` decorator is deprecated, and will be removed in version 1.0.0. Refer to " # noqa: E501 + "https://www.starlette.io/routing/#websocket-routing for the recommended approach.", # noqa: E501 + DeprecationWarning, + ) def decorator(func: typing.Callable) -> typing.Callable: self.add_websocket_route(path, func, name=name) @@ -860,7 +836,13 @@ else: self.on_shutdown.append(func) - def on_event(self, event_type: str) -> typing.Callable: # pragma: nocover + def on_event(self, event_type: str) -> typing.Callable: + warnings.warn( + "The `on_event` decorator is deprecated, and will be removed in version 1.0.0. " # noqa: E501 + "Refer to https://www.starlette.io/events/#registering-events for recommended approach.", # noqa: E501 + DeprecationWarning, + ) + def decorator(func: typing.Callable) -> typing.Callable: self.add_event_handler(event_type, func) return func diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/starlette/testclient.py new/starlette-0.23.1/starlette/testclient.py --- old/starlette-0.22.0/starlette/testclient.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/starlette/testclient.py 2022-12-09 15:45:37.000000000 +0100 @@ -368,6 +368,7 @@ backend: str = "asyncio", backend_options: typing.Optional[typing.Dict[str, typing.Any]] = None, cookies: httpx._client.CookieTypes = None, + headers: typing.Dict[str, str] = None, ) -> None: self.async_backend = _AsyncBackend( backend=backend, backend_options=backend_options or {} @@ -385,10 +386,13 @@ raise_server_exceptions=raise_server_exceptions, root_path=root_path, ) + if headers is None: + headers = {} + headers.setdefault("user-agent", "testclient") super().__init__( app=self.app, base_url=base_url, - headers={"user-agent": "testclient"}, + headers=headers, transport=transport, follow_redirects=True, cookies=cookies, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/tests/middleware/test_gzip.py new/starlette-0.23.1/tests/middleware/test_gzip.py --- old/starlette-0.22.0/tests/middleware/test_gzip.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/tests/middleware/test_gzip.py 2022-12-09 15:45:37.000000000 +0100 @@ -86,7 +86,7 @@ streaming = generator(bytes=b"x" * 400, count=10) return StreamingResponse( - streaming, status_code=200, headers={"Content-Encoding": "br"} + streaming, status_code=200, headers={"Content-Encoding": "text"} ) app = Starlette( @@ -95,8 +95,8 @@ ) client = test_client_factory(app) - response = client.get("/", headers={"accept-encoding": "gzip, br"}) + response = client.get("/", headers={"accept-encoding": "gzip, text"}) assert response.status_code == 200 assert response.text == "x" * 4000 - assert response.headers["Content-Encoding"] == "br" + assert response.headers["Content-Encoding"] == "text" assert "Content-Length" not in response.headers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/tests/test_applications.py new/starlette-0.23.1/tests/test_applications.py --- old/starlette-0.22.0/tests/test_applications.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/tests/test_applications.py 2022-12-09 15:45:37.000000000 +0100 @@ -429,3 +429,60 @@ assert not cleanup_complete assert startup_complete assert cleanup_complete + + +def test_decorator_deprecations() -> None: + app = Starlette() + + with pytest.deprecated_call( + match=( + "The `exception_handler` decorator is deprecated, " + "and will be removed in version 1.0.0." + ) + ) as record: + app.exception_handler(500)(http_exception) + assert len(record) == 1 + + with pytest.deprecated_call( + match=( + "The `middleware` decorator is deprecated, " + "and will be removed in version 1.0.0." + ) + ) as record: + + async def middleware(request, call_next): + ... # pragma: no cover + + app.middleware("http")(middleware) + assert len(record) == 1 + + with pytest.deprecated_call( + match=( + "The `route` decorator is deprecated, " + "and will be removed in version 1.0.0." + ) + ) as record: + app.route("/")(async_homepage) + assert len(record) == 1 + + with pytest.deprecated_call( + match=( + "The `websocket_route` decorator is deprecated, " + "and will be removed in version 1.0.0." + ) + ) as record: + app.websocket_route("/ws")(websocket_endpoint) + assert len(record) == 1 + + with pytest.deprecated_call( + match=( + "The `on_event` decorator is deprecated, " + "and will be removed in version 1.0.0." + ) + ) as record: + + async def startup(): + ... # pragma: no cover + + app.on_event("startup")(startup) + assert len(record) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/tests/test_convertors.py new/starlette-0.23.1/tests/test_convertors.py --- old/starlette-0.22.0/tests/test_convertors.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/tests/test_convertors.py 2022-12-09 15:45:37.000000000 +0100 @@ -54,3 +54,17 @@ app.url_path_for("datetime-convertor", param=datetime(1996, 1, 22, 23, 0, 0)) == "/datetime/1996-01-22T23:00:00" ) + + +@pytest.mark.parametrize("param, status_code", [("1.0", 200), ("1-0", 404)]) +def test_default_float_convertor(test_client_factory, param: str, status_code: int): + def float_convertor(request): + param = request.path_params["param"] + assert isinstance(param, float) + return JSONResponse({"float": param}) + + app = Router(routes=[Route("/{param:float}", endpoint=float_convertor)]) + + client = test_client_factory(app) + response = client.get(f"/{param}") + assert response.status_code == status_code diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/tests/test_routing.py new/starlette-0.23.1/tests/test_routing.py --- old/starlette-0.22.0/tests/test_routing.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/tests/test_routing.py 2022-12-09 15:45:37.000000000 +0100 @@ -1020,3 +1020,20 @@ ) # test for substring because repr(Router) returns unique object ID assert repr(route).startswith("Host(host='example.com', name='app', app=") + + +def test_decorator_deprecations() -> None: + router = Router() + + with pytest.deprecated_call(): + router.route("/")(homepage) + + with pytest.deprecated_call(): + router.websocket_route("/ws")(websocket_endpoint) + + with pytest.deprecated_call(): + + async def startup() -> None: + ... # pragma: nocover + + router.on_event("startup")(startup) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/starlette-0.22.0/tests/test_testclient.py new/starlette-0.23.1/tests/test_testclient.py --- old/starlette-0.22.0/tests/test_testclient.py 2022-11-17 07:24:34.000000000 +0100 +++ new/starlette-0.23.1/tests/test_testclient.py 2022-12-09 15:45:37.000000000 +0100 @@ -11,6 +11,7 @@ from starlette.middleware import Middleware from starlette.responses import JSONResponse, Response from starlette.routing import Route +from starlette.testclient import TestClient from starlette.websockets import WebSocket, WebSocketDisconnect @@ -67,6 +68,25 @@ assert response.json() == {"mock": "example"} +def test_testclient_headers_behavior(): + """ + We should be able to use the test client with user defined headers. + + This is useful if we need to set custom headers for authentication + during tests or in development. + """ + + client = TestClient(mock_service) + assert client.headers.get("user-agent") == "testclient" + + client = TestClient(mock_service, headers={"user-agent": "non-default-agent"}) + assert client.headers.get("user-agent") == "non-default-agent" + + client = TestClient(mock_service, headers={"Authentication": "Bearer 123"}) + assert client.headers.get("user-agent") == "testclient" + assert client.headers.get("Authentication") == "Bearer 123" + + def test_use_testclient_as_contextmanager(test_client_factory, anyio_backend_name): """ This test asserts a number of properties that are important for an