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

WebSocketRoute does not work with functools.partial #1355

Closed
2 tasks done
connection-reset opened this issue Dec 10, 2021 · 1 comment · Fixed by #1356
Closed
2 tasks done

WebSocketRoute does not work with functools.partial #1355

connection-reset opened this issue Dec 10, 2021 · 1 comment · Fixed by #1356
Labels
feature New feature or request websocket WebSocket-related

Comments

@connection-reset
Copy link

connection-reset commented Dec 10, 2021

Checklist

  • The bug is reproducible against the latest release and/or master.
  • There are no similar issues or pull requests to fix it yet.

Describe the bug

Accessing a WebSocketRoute with async function wrapped in functools.partial raises TypeError.

To reproduce

import functools
from starlette.applications import Starlette
from starlette.routing import WebSocketRoute

async def handle_ws(ws):
    pass

app = Starlette(debug=True, routes=[
    WebSocketRoute("/", functools.partial(handle_ws)),
])

Install uvicorn[standard], run with uvicorn bug:app.
Access ws://localhost:8000 with e.g. wscat.

Expected behavior

WebSocketRoute should work with functools.partial just like Route.

Actual behavior

The route fails because it is treated as an ASGI application (ref.

if inspect.isfunction(endpoint) or inspect.ismethod(endpoint):
# Endpoint is function or method. Treat it as `func(websocket)`.
self.app = websocket_session(endpoint)
else:
# Endpoint is a class. Treat it as ASGI.
self.app = endpoint
).

Debugging material

Traceback (most recent call last):
  File "/tmp/bug/venv/lib/python3.9/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 199, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/tmp/bug/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/tmp/bug/venv/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/tmp/bug/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "/tmp/bug/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "/tmp/bug/venv/lib/python3.9/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/tmp/bug/venv/lib/python3.9/site-packages/starlette/routing.py", line 315, in handle
    await self.app(scope, receive, send)
TypeError: handle_ws() takes 1 positional argument but 3 were given

Environment

  • OS: Arch Linux
  • Python version: 3.9.9
  • Starlette version: 0.17.1

Additional context

Support for functools.partial for Route was introduced in #984.
Those changes to Route.__init__ fix this bug too but just copying them feels unsustainable.

@Kludex
Copy link
Sponsor Member

Kludex commented Dec 10, 2021

Sounds reasonable. PR is welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request websocket WebSocket-related
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants