diff --git a/sanic/blueprints.py b/sanic/blueprints.py index 508e25ac..37a451a8 100644 --- a/sanic/blueprints.py +++ b/sanic/blueprints.py @@ -305,6 +305,16 @@ class Blueprint(BaseSanic): listeners = defaultdict(list) registered = set() + # Get routes by (uri, overwirting) + _overwritten_routes = {(_future.uri, _future.overwrite): _future + for _future in self._future_routes} + for _key, _future in _overwritten_routes.items(): + if _future.overwrite: + # Find same route if overwritten, remove it from "route set" + _other_same_route = _overwritten_routes.get((_future.uri, False)) + if _other_same_route: + self._future_routes.remove(_other_same_route) + # Routes for future in self._future_routes: # Prepend the blueprint URI prefix if available @@ -348,6 +358,7 @@ class Blueprint(BaseSanic): version_prefix, error_format, future.route_context, + future.overwrite, # 补充overwrite参数 ) if (self, apply_route) in app._future_registry: diff --git a/sanic/mixins/routes.py b/sanic/mixins/routes.py index 49540279..f8decae9 100644 --- a/sanic/mixins/routes.py +++ b/sanic/mixins/routes.py @@ -97,6 +97,7 @@ class RouteMixin(BaseMixin, metaclass=SanicMeta): if not methods and not websocket: methods = frozenset({"GET"}) + overwrite = ctx_kwargs.pop("overwrite", False) route_context = self._build_route_context(ctx_kwargs) def decorator(handler): @@ -113,6 +114,7 @@ class RouteMixin(BaseMixin, metaclass=SanicMeta): nonlocal static nonlocal version_prefix nonlocal error_format + nonlocal overwrite if isinstance(handler, tuple): # if a handler fn is already wrapped in a route, the handler @@ -158,6 +160,7 @@ class RouteMixin(BaseMixin, metaclass=SanicMeta): version_prefix, error_format, route_context, + overwrite ) self._future_routes.add(route) diff --git a/sanic/models/futures.py b/sanic/models/futures.py index f9e0644c..c9b99cda 100644 --- a/sanic/models/futures.py +++ b/sanic/models/futures.py @@ -28,6 +28,7 @@ class FutureRoute(NamedTuple): version_prefix: str error_format: Optional[str] route_context: HashableDict + overwrite: bool = False class FutureListener(NamedTuple): diff --git a/sanic/router.py b/sanic/router.py index a469fd21..6b5fdcaf 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -81,6 +81,7 @@ class Router(BaseRouter): static: bool = False, version_prefix: str = "/v", error_format: Optional[str] = None, + overwrite: bool = False, ) -> Union[Route, List[Route]]: """ Add a handler to the router @@ -122,6 +123,7 @@ class Router(BaseRouter): name=name, strict=strict_slashes, unquote=unquote, + overwrite=overwrite, ) if isinstance(host, str): @@ -150,6 +152,7 @@ class Router(BaseRouter): route.extra.hosts = hosts route.extra.static = static route.extra.error_format = error_format + route.extra.overwrite = overwrite if error_format: check_error_format(route.extra.error_format)