Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for custom name generation #2961

Merged
merged 6 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sanic/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ def register(self, app, options):
name = future.name
if opt_name_prefix:
name = f"{opt_name_prefix}_{future.name}"
name = app._generate_name(name)
name = app.generate_name(name)
host = future.host or self.host
if isinstance(host, list):
host = tuple(host)
Expand Down
49 changes: 28 additions & 21 deletions sanic/mixins/base.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
from typing import Optional
from typing import Optional, Protocol, Union

from sanic.base.meta import SanicMeta


class NameProtocol(Protocol):
name: str


class DunderNameProtocol(Protocol):
__name__: str


class BaseMixin(metaclass=SanicMeta):
"""Base class for some other mixins."""
"""Base class for various mixins."""

name: str
strict_slashes: Optional[bool]

def _generate_name(self, *objects) -> str:
name = None

def _generate_name(
self, *objects: Union[NameProtocol, DunderNameProtocol, str]
) -> str:
print(objects)
name: Optional[str] = None
for obj in objects:
if obj:
if isinstance(obj, str):
name = obj
break

try:
name = obj.name
except AttributeError:
try:
name = obj.__name__
except AttributeError:
continue
else:
break

if not name: # noqa
if not obj:
continue
if isinstance(obj, str):
name = obj
else:
name = getattr(obj, "name", getattr(obj, "__name__", None))

if name:
break
if not name or not isinstance(name, str):
raise ValueError("Could not generate a name for handler")

if not name.startswith(f"{self.name}."):
name = f"{self.name}.{name}"

return name

def generate_name(self, *objects) -> str:
return self._generate_name(*objects)
2 changes: 1 addition & 1 deletion sanic/mixins/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def decorator(handler):
# variable will be a tuple of (existing routes, handler fn)
_, handler = handler

name = self._generate_name(name, handler)
name = self.generate_name(name, handler)

if isinstance(host, str):
host = frozenset([host])
Expand Down
2 changes: 1 addition & 1 deletion sanic/mixins/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def static(
```
""" # noqa: E501

name = self._generate_name(name)
name = self.generate_name(name)

if strict_slashes is None and self.strict_slashes is not None:
strict_slashes = self.strict_slashes
Expand Down
2 changes: 1 addition & 1 deletion sanic/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def find_route_by_view_name(

route = self.name_index.get(view_name)
if not route:
full_name = self.ctx.app._generate_name(view_name)
full_name = self.ctx.app.generate_name(view_name)
route = self.name_index.get(full_name)

if not route:
Expand Down
Loading