Skip to content

Commit

Permalink
Allow route decorators to stack up again (#1764)
Browse files Browse the repository at this point in the history
* Allow route decorators to stack up without causing a function signature inspection crash
Fix #1742

* Apply fix to @websocket routes docorator too
Add test for double-stacked websocket decorator
remove introduction of new variable in route wrapper, extend routes in-place.
Add explanation of why a handler will be a tuple in the case of a double-stacked route decorator
  • Loading branch information
ashleysommer authored and yunstanford committed Jan 11, 2020
1 parent caa1b4d commit b565072
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 15 deletions.
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

0 comments on commit b565072

Please sign in to comment.