Allow empty lazy, and multiple pre-registrations

This commit is contained in:
Adam Hopkins 2021-12-15 09:12:56 +02:00
parent 6d3f1e9982
commit 266af1e279
No known key found for this signature in database
GPG Key ID: 9F85EE6C807303FB
2 changed files with 38 additions and 20 deletions

View File

@ -50,7 +50,7 @@ from sanic_routing.exceptions import ( # type: ignore
) )
from sanic_routing.route import Route # type: ignore from sanic_routing.route import Route # type: ignore
from sanic import blueprint_group, reloader_helpers from sanic import reloader_helpers
from sanic.application.logo import get_logo from sanic.application.logo import get_logo
from sanic.application.motd import MOTD from sanic.application.motd import MOTD
from sanic.application.state import ApplicationState, Mode from sanic.application.state import ApplicationState, Mode
@ -67,6 +67,7 @@ from sanic.exceptions import (
URLBuildError, URLBuildError,
) )
from sanic.handlers import ErrorHandler from sanic.handlers import ErrorHandler
from sanic.helpers import Default, _default
from sanic.http import Stage from sanic.http import Stage
from sanic.log import LOGGING_CONFIG_DEFAULTS, Colors, error_logger, logger from sanic.log import LOGGING_CONFIG_DEFAULTS, Colors, error_logger, logger
from sanic.mixins.listeners import ListenerEvent from sanic.mixins.listeners import ListenerEvent
@ -537,10 +538,25 @@ class Sanic(BaseSanic, metaclass=TouchUpMeta):
blueprint.register(self, options) blueprint.register(self, options)
def _register_lazy_blueprints(self): def _register_lazy_blueprints(self):
for name, reg_info in Blueprint.__pre_registry__.items(): registry = {**Blueprint.__pre_registry__}
blueprint = reg_info.pop("bp") if _default in Blueprint.__pre_registry__:
if name == self.name and blueprint.name not in self.blueprints: if len(Sanic._app_registry) > 1:
self.blueprint(blueprint, **reg_info) raise SanicException(
"Ambiguous Blueprint pre-registration detected. When "
"there are multiple Sanic application instances, all "
"pre-registrations must use an application name."
)
registry = {
self.name if k is _default else k: v
for k, v in registry.items()
}
for name, registrants in registry.items():
for reg_info in registrants:
blueprint = reg_info.pop("bp")
if name == self.name and blueprint.name not in self.blueprints:
self.blueprint(blueprint, **reg_info)
def url_for(self, view_name: str, **kwargs): def url_for(self, view_name: str, **kwargs):
"""Build a URL based on a view name and the values provided. """Build a URL based on a view name and the values provided.
@ -1686,7 +1702,7 @@ class Sanic(BaseSanic, metaclass=TouchUpMeta):
@classmethod @classmethod
def lazy( def lazy(
cls, cls,
app_name: str, app_name: Union[str, Default] = _default,
*, *,
name: str = None, name: str = None,
url_prefix: Optional[str] = None, url_prefix: Optional[str] = None,

View File

@ -107,7 +107,7 @@ class Blueprint(BaseSanic):
"version_prefix", "version_prefix",
"websocket_routes", "websocket_routes",
) )
__pre_registry__: Dict[str, Any] = {} __pre_registry__: Dict[Union[str, Default], Any] = defaultdict(list)
def __init__( def __init__(
self, self,
@ -465,22 +465,24 @@ class Blueprint(BaseSanic):
def pre_register( def pre_register(
self, self,
name: str = None, name: Union[str, Default],
url_prefix: Optional[str] = None, url_prefix: Optional[str] = None,
host: Optional[Union[List[str], str]] = None, host: Optional[Union[List[str], str]] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
version_prefix: Union[str, Default] = _default, version_prefix: Union[str, Default] = _default,
) -> None: ) -> None:
self.__class__.__pre_registry__[name] = { self.__class__.__pre_registry__[name].append(
k: v {
for k, v in { k: v
"bp": self, for k, v in {
"url_prefix": url_prefix, "bp": self,
"host": host, "url_prefix": url_prefix,
"version": version, "host": host,
"strict_slashes": strict_slashes, "version": version,
"version_prefix": version_prefix, "strict_slashes": strict_slashes,
}.items() "version_prefix": version_prefix,
if v is not None and v is not _default }.items()
} if v is not None and v is not _default
}
)