Deprecate the legacy websockets implementation and default `auto` to websockets-sansio
Merged
KL
5mo ago+275+275+012345678901234567890123456789-221-221-012345678901234567890123456789
Moves --ws auto away from the legacy websockets implementation, in preparation for removing it entirely.
--ws autonow resolves toWebSocketsSansIOProtocolwhenwebsocketsis installed (wsproto fallback unchanged).- Importing the legacy implementation (via
--ws websocketsor directly) emits aUvicornDeprecationWarning- a newUserWarningsubclass exported from the package root so it is visible by default, following the Starlette approach. - The legacy
WebSocketProtocolis no longer tested: removed from thews_protocol_clsmatrix and excluded from coverage. - Tests migrated from the deprecated
websockets.clientAPI towebsockets.asyncio.client, allowing the dev pin to move fromwebsockets==13.1towebsockets==16.0and dropping the four websocketsfilterwarningsignores. uvicorn[standard]floor bumped towebsockets>=11.0, the first version with the sans-ioServerProtocolthat the default implementation now requires.
Notes from the migration:
- The sansio implementation rejects oversized frames from the frame header instead of buffering the whole message first (better memory behavior than legacy). The abrupt close means a mid-send client can observe 1006 instead of 1009, so the
ws_max_sizetest now asserts the close code the server delivers to the app viawebsocket.disconnect. - Found an upstream
websocketsedge case while migrating: with permessage-deflate, a compressed message whose decompressed size barely exceedsmax_size(~1-2 bytes) is silently truncated tomax_sizeinstead of rejected with 1009 - theunconsumed_tailcheck misses it when all compressed input was consumed. Larger overages are caught. Will report upstream; the affected test disables compression so wire sizes are what is being tested.
Next steps (separate PRs): point the websockets string at WebSocketsSansIOProtocol, alias WebSocketProtocol to it, and deprecate --ws-max-queue (the sansio implementation applies backpressure via pause_reading instead of a bounded queue).
AI Disclaimer
This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.