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 route decorators to stack up again #1764

Merged
merged 3 commits into from
Jan 11, 2020
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
47 changes: 32 additions & 15 deletions sanic/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ def route(
strict_slashes = self.strict_slashes

def response(handler):
if isinstance(handler, tuple):
# if a handler fn is already wrapped in a route, the handler
# variable will be a tuple of (existing routes, handler fn)
routes, handler = handler
else:
routes = []
args = list(signature(handler).parameters.keys())

if not args:
Expand All @@ -205,14 +211,16 @@ def response(handler):
if stream:
handler.is_stream = stream

routes = self.router.add(
uri=uri,
methods=methods,
handler=handler,
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
routes.extend(
self.router.add(
uri=uri,
methods=methods,
handler=handler,
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
)
)
return routes, handler

Expand Down Expand Up @@ -476,6 +484,13 @@ def websocket(
strict_slashes = self.strict_slashes

def response(handler):
if isinstance(handler, tuple):
# if a handler fn is already wrapped in a route, the handler
# variable will be a tuple of (existing routes, handler fn)
routes, handler = handler
else:
routes = []

async def websocket_handler(request, *args, **kwargs):
request.app = self
if not getattr(handler, "__blueprintname__", False):
Expand Down Expand Up @@ -516,13 +531,15 @@ async def websocket_handler(request, *args, **kwargs):
self.websocket_tasks.remove(fut)
await ws.close()

routes = self.router.add(
uri=uri,
handler=websocket_handler,
methods=frozenset({"GET"}),
host=host,
strict_slashes=strict_slashes,
name=name,
routes.extend(
self.router.add(
uri=uri,
handler=websocket_handler,
methods=frozenset({"GET"}),
host=host,
strict_slashes=strict_slashes,
name=name,
)
)
return routes, handler

Expand Down
29 changes: 29 additions & 0 deletions tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,35 @@ async def handler4(request, dynamic):
pass


def test_double_stack_route(app):
@app.route("/test/1")
@app.route("/test/2")
async def handler1(request):
return text("OK")

request, response = app.test_client.get("/test/1")
assert response.status == 200
request, response = app.test_client.get("/test/2")
assert response.status == 200


@pytest.mark.asyncio
async def test_websocket_route_asgi(app):
ev = asyncio.Event()

@app.websocket("/test/1")
@app.websocket("/test/2")
async def handler(request, ws):
ev.set()

request, response = await app.asgi_client.websocket("/test/1")
first_set = ev.is_set()
ev.clear()
request, response = await app.asgi_client.websocket("/test/1")
second_set = ev.is_set()
assert(first_set and second_set)


def test_method_not_allowed(app):
@app.route("/test", methods=["GET"])
async def handler(request):
Expand Down