From d7cbe2a4887ad6b15fe7523ed62e28a426b7697d Mon Sep 17 00:00:00 2001 From: Felix Fanghaenel <35657654+flxdot@users.noreply.github.com> Date: Fri, 8 Apr 2022 20:53:17 +0200 Subject: [PATCH] Apply right name to `Route` when created from methods (#1553) * add support to read route names from methods * simplify implementation * add tests for automatic route naming * simplify tests * Apply suggestions from code review * Update tests/test_routing.py * format with black * Apply suggestions from code review Co-authored-by: Marcelo Trylesinski --- starlette/routing.py | 2 +- tests/test_routing.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/starlette/routing.py b/starlette/routing.py index 0388304c9..ea6ec2117 100644 --- a/starlette/routing.py +++ b/starlette/routing.py @@ -84,7 +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.isclass(endpoint): + if inspect.isroutine(endpoint) or inspect.isclass(endpoint): return endpoint.__name__ return endpoint.__class__.__name__ diff --git a/tests/test_routing.py b/tests/test_routing.py index 7077c5616..e8adaca48 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1,4 +1,5 @@ import functools +import typing import uuid import pytest @@ -710,3 +711,38 @@ def test_duplicated_param_names(): match="Duplicated param names id, name at path /{id}/{name}/{id}/{name}", ): Route("/{id}/{name}/{id}/{name}", user) + + +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( + "endpoint, expected_name", + [ + 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_staticmethod, + "my_staticmethod", + id="staticmethod", + ), + pytest.param(Endpoint(), "Endpoint", id="object"), + pytest.param(lambda request: ..., "", id="lambda"), + ], +) +def test_route_name(endpoint: typing.Callable, expected_name: str): + assert Route(path="/", endpoint=endpoint).name == expected_name