From 2ba3353e388d94a10dba9bbf6ff8178f5a6f4100 Mon Sep 17 00:00:00 2001 From: Felix Fanghanel Date: Fri, 25 Mar 2022 11:08:35 +0100 Subject: [PATCH 1/8] add support to read route names from methods --- starlette/routing.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/starlette/routing.py b/starlette/routing.py index 0388304c9..ce53e7fb1 100644 --- a/starlette/routing.py +++ b/starlette/routing.py @@ -84,7 +84,11 @@ async def app(scope: Scope, receive: Receive, send: Send) -> None: def get_name(endpoint: typing.Callable) -> str: - if inspect.isfunction(endpoint) or inspect.isclass(endpoint): + if ( + inspect.isfunction(endpoint) + or inspect.ismethod(endpoint) + or inspect.isclass(endpoint) + ): return endpoint.__name__ return endpoint.__class__.__name__ From c269b220158dc7b6d01b38d75e67a72acb59c3c8 Mon Sep 17 00:00:00 2001 From: Felix Fanghanel Date: Mon, 28 Mar 2022 08:44:56 +0200 Subject: [PATCH 2/8] simplify implementation --- starlette/routing.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/starlette/routing.py b/starlette/routing.py index ce53e7fb1..ea6ec2117 100644 --- a/starlette/routing.py +++ b/starlette/routing.py @@ -84,11 +84,7 @@ async def app(scope: Scope, receive: Receive, send: Send) -> None: def get_name(endpoint: typing.Callable) -> str: - if ( - inspect.isfunction(endpoint) - or inspect.ismethod(endpoint) - or inspect.isclass(endpoint) - ): + if inspect.isroutine(endpoint) or inspect.isclass(endpoint): return endpoint.__name__ return endpoint.__class__.__name__ From 9831f623a5f4c93c758fe03bfd53902464a88b5b Mon Sep 17 00:00:00 2001 From: Felix Fanghanel Date: Fri, 8 Apr 2022 17:32:30 +0200 Subject: [PATCH 3/8] add tests for automatic route naming --- tests/test_routing.py | 62 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/tests/test_routing.py b/tests/test_routing.py index 7077c5616..f0b6636b4 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1,11 +1,20 @@ import functools import uuid +import typing import pytest from starlette.applications import Starlette from starlette.responses import JSONResponse, PlainTextResponse, Response -from starlette.routing import Host, Mount, NoMatchFound, Route, Router, WebSocketRoute +from starlette.routing import ( + get_name, + Host, + Mount, + NoMatchFound, + Route, + Router, + WebSocketRoute, +) from starlette.websockets import WebSocket, WebSocketDisconnect @@ -710,3 +719,54 @@ def test_duplicated_param_names(): match="Duplicated param names id, name at path /{id}/{name}/{id}/{name}", ): Route("/{id}/{name}/{id}/{name}", user) + + +class EndpointCollectionObject: + async def my_method(self, request): + return JSONResponse({"endpoint_type": "method"}) + + @classmethod + async def my_classmethod(self, request): + return JSONResponse({"endpoint_type": "classmethod"}) + + @staticmethod + async def my_staticmethod(self, request): + return JSONResponse({"endpoint_type": "staticmethod"}) + + +class EndpointObject: + def __call__(self, request): + return JSONResponse({"endpoint_type": "class"}) + + +@pytest.mark.parametrize( + "endpoint, expected_name", + [ + pytest.param(func_homepage, "func_homepage", id="function"), + pytest.param(EndpointCollectionObject().my_method, "my_method", id="method"), + pytest.param( + EndpointCollectionObject.my_classmethod, "my_classmethod", id="classmethod" + ), + pytest.param( + EndpointCollectionObject.my_staticmethod, + "my_staticmethod", + id="staticmethod", + ), + pytest.param(EndpointObject, "EndpointObject", id="object"), + pytest.param( + lambda request: JSONResponse({"endpoint_type": "lambda"}), + "", + id="lambda", + ), + ], +) +def test_route_name_automatic(endpoint: typing.Callable, expected_name: str): + + # Path does not matter here, as we only care about how the route name is created. + assert Route(path="/", endpoint=endpoint).name == expected_name + + +def test_route_name_manual(): + + name = "my_custom_endpoint" + assert Route(path="/", endpoint=func_homepage, name=name).name == name From 4d2dc29fdd0db3817d5d9cac4bc00ffa4cd1591b Mon Sep 17 00:00:00 2001 From: Felix Fanghanel Date: Fri, 8 Apr 2022 19:15:12 +0200 Subject: [PATCH 4/8] simplify tests --- tests/test_routing.py | 50 ++++++++++++------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/tests/test_routing.py b/tests/test_routing.py index f0b6636b4..54b2f8630 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -6,15 +6,8 @@ from starlette.applications import Starlette from starlette.responses import JSONResponse, PlainTextResponse, Response -from starlette.routing import ( - get_name, - Host, - Mount, - NoMatchFound, - Route, - Router, - WebSocketRoute, -) +from starlette.routing import Host, Mount, NoMatchFound, Route, Router, WebSocketRoute + from starlette.websockets import WebSocket, WebSocketDisconnect @@ -721,52 +714,37 @@ def test_duplicated_param_names(): Route("/{id}/{name}/{id}/{name}", user) -class EndpointCollectionObject: +class Endpoint: async def my_method(self, request): - return JSONResponse({"endpoint_type": "method"}) + ... @classmethod - async def my_classmethod(self, request): - return JSONResponse({"endpoint_type": "classmethod"}) + async def my_classmethod(cls, request): + ... @staticmethod async def my_staticmethod(self, request): - return JSONResponse({"endpoint_type": "staticmethod"}) + ... - -class EndpointObject: def __call__(self, request): - return JSONResponse({"endpoint_type": "class"}) + ... @pytest.mark.parametrize( "endpoint, expected_name", [ pytest.param(func_homepage, "func_homepage", id="function"), - pytest.param(EndpointCollectionObject().my_method, "my_method", id="method"), - pytest.param( - EndpointCollectionObject.my_classmethod, "my_classmethod", id="classmethod" - ), + pytest.param(Endpoint().my_method, "my_method", id="method"), pytest.param( - EndpointCollectionObject.my_staticmethod, - "my_staticmethod", - id="staticmethod", + Endpoint.my_classmethod, "my_classmethod", id="classmethod" ), - pytest.param(EndpointObject, "EndpointObject", id="object"), pytest.param( - lambda request: JSONResponse({"endpoint_type": "lambda"}), - "", - id="lambda", + Endpoint.my_staticmethod, "my_staticmethod", id="staticmethod", ), + pytest.param(Endpoint(), "Endpoint", id="object"), + pytest.param(lambda request: ..., "", id="lambda"), ], ) -def test_route_name_automatic(endpoint: typing.Callable, expected_name: str): +def test_route_name(endpoint: typing.Callable, expected_name: str): - # Path does not matter here, as we only care about how the route name is created. assert Route(path="/", endpoint=endpoint).name == expected_name - - -def test_route_name_manual(): - - name = "my_custom_endpoint" - assert Route(path="/", endpoint=func_homepage, name=name).name == name From a0655d6248ffa97fc333be1bd192f76aaa2e7fc1 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 8 Apr 2022 20:04:28 +0200 Subject: [PATCH 5/8] Apply suggestions from code review --- tests/test_routing.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_routing.py b/tests/test_routing.py index 54b2f8630..060a383e3 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -7,7 +7,6 @@ from starlette.applications import Starlette from starlette.responses import JSONResponse, PlainTextResponse, Response from starlette.routing import Host, Mount, NoMatchFound, Route, Router, WebSocketRoute - from starlette.websockets import WebSocket, WebSocketDisconnect @@ -723,7 +722,7 @@ async def my_classmethod(cls, request): ... @staticmethod - async def my_staticmethod(self, request): + async def my_staticmethod(request): ... def __call__(self, request): @@ -746,5 +745,4 @@ def __call__(self, request): ], ) def test_route_name(endpoint: typing.Callable, expected_name: str): - assert Route(path="/", endpoint=endpoint).name == expected_name From 2635947d01d97c219bc46c766462d22002dfa820 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 8 Apr 2022 20:06:15 +0200 Subject: [PATCH 6/8] Update tests/test_routing.py --- tests/test_routing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_routing.py b/tests/test_routing.py index 060a383e3..8ddbaa514 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1,6 +1,6 @@ import functools -import uuid import typing +import uuid import pytest From 64c6f6c4a14a628d5c85950519b1cf79bb01d618 Mon Sep 17 00:00:00 2001 From: Felix Fanghanel Date: Fri, 8 Apr 2022 20:30:52 +0200 Subject: [PATCH 7/8] format with black --- tests/test_routing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_routing.py b/tests/test_routing.py index 8ddbaa514..d3ad772af 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -734,11 +734,11 @@ def __call__(self, request): [ pytest.param(func_homepage, "func_homepage", id="function"), pytest.param(Endpoint().my_method, "my_method", id="method"), + pytest.param(Endpoint.my_classmethod, "my_classmethod", id="classmethod"), pytest.param( - Endpoint.my_classmethod, "my_classmethod", id="classmethod" - ), - pytest.param( - Endpoint.my_staticmethod, "my_staticmethod", id="staticmethod", + Endpoint.my_staticmethod, + "my_staticmethod", + id="staticmethod", ), pytest.param(Endpoint(), "Endpoint", id="object"), pytest.param(lambda request: ..., "", id="lambda"), From cc99f1f0babf1009d575ef6690c9f4782fa997a6 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 8 Apr 2022 20:35:29 +0200 Subject: [PATCH 8/8] Apply suggestions from code review --- tests/test_routing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_routing.py b/tests/test_routing.py index d3ad772af..e8adaca48 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -715,18 +715,18 @@ def test_duplicated_param_names(): class Endpoint: async def my_method(self, request): - ... + ... # pragma: no cover @classmethod async def my_classmethod(cls, request): - ... + ... # pragma: no cover @staticmethod async def my_staticmethod(request): - ... + ... # pragma: no cover def __call__(self, request): - ... + ... # pragma: no cover @pytest.mark.parametrize(