Skip to content

Commit 808d854

Browse files
committed
Replace asyncio.wait_for with asyncio.timeout.
Some instances were missed in a previous commit. Also update documentation.
1 parent 5a6f74e commit 808d854

File tree

6 files changed

+21
-13
lines changed

6 files changed

+21
-13
lines changed

docs/faq/common.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,14 @@ you can adjust it with the ``ping_timeout`` argument.
105105
How do I set a timeout on :meth:`~legacy.protocol.WebSocketCommonProtocol.recv`?
106106
--------------------------------------------------------------------------------
107107

108-
Use :func:`~asyncio.wait_for`::
108+
On Python ≥ 3.11, use :func:`asyncio.timeout`::
109109

110-
await asyncio.wait_for(websocket.recv(), timeout=10)
110+
async with asyncio.timeout(timeout=10):
111+
message = await websocket.recv()
112+
113+
On older versions of Python, use :func:`asyncio.wait_for`::
114+
115+
message = await asyncio.wait_for(websocket.recv(), timeout=10)
111116

112117
This technique works for most APIs. When it doesn't, for example with
113118
asynchronous context managers, websockets provides an ``open_timeout`` argument.

docs/topics/design.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ propagate cancellation to them.
437437
prevent cancellation.
438438

439439
:meth:`~legacy.protocol.WebSocketCommonProtocol.close` waits for the data transfer
440-
task to terminate with :func:`~asyncio.wait_for`. If it's canceled or if the
440+
task to terminate with :func:`~asyncio.timeout`. If it's canceled or if the
441441
timeout elapses, :attr:`~legacy.protocol.WebSocketCommonProtocol.transfer_data_task`
442442
is canceled, which is correct at this point.
443443
:meth:`~legacy.protocol.WebSocketCommonProtocol.close` then waits for

src/websockets/legacy/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from ..http import USER_AGENT
4545
from ..typing import ExtensionHeader, LoggerLike, Origin, Subprotocol
4646
from ..uri import WebSocketURI, parse_uri
47+
from .compatibility import asyncio_timeout
4748
from .handshake import build_request, check_response
4849
from .http import read_response
4950
from .protocol import WebSocketCommonProtocol
@@ -650,7 +651,8 @@ def __await__(self) -> Generator[Any, None, WebSocketClientProtocol]:
650651
return self.__await_impl_timeout__().__await__()
651652

652653
async def __await_impl_timeout__(self) -> WebSocketClientProtocol:
653-
return await asyncio.wait_for(self.__await_impl__(), self.open_timeout)
654+
async with asyncio_timeout(self.open_timeout):
655+
return await self.__await_impl__()
654656

655657
async def __await_impl__(self) -> WebSocketClientProtocol:
656658
for redirects in range(self.MAX_REDIRECTS_ALLOWED):

src/websockets/legacy/protocol.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ class WebSocketCommonProtocol(asyncio.Protocol):
107107
context manager;
108108
* on the server side, when the connection handler terminates.
109109
110-
To apply a timeout to any other API, wrap it in :func:`~asyncio.wait_for`.
110+
To apply a timeout to any other API, wrap it in :func:`~asyncio.timeout` or
111+
:func:`~asyncio.wait_for`.
111112
112113
The ``max_size`` parameter enforces the maximum size for incoming messages
113114
in bytes. The default value is 1 MiB. If a larger message is received,
@@ -513,7 +514,7 @@ async def recv(self) -> Data:
513514
message. The next invocation of :meth:`recv` will return it.
514515
515516
This makes it possible to enforce a timeout by wrapping :meth:`recv` in
516-
:func:`~asyncio.wait_for`.
517+
:func:`~asyncio.timeout` or :func:`~asyncio.wait_for`.
517518
518519
Returns:
519520
Data: A string (:class:`str`) for a Text_ frame. A bytestring

src/websockets/legacy/server.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
from ..http import USER_AGENT
4747
from ..protocol import State
4848
from ..typing import ExtensionHeader, LoggerLike, Origin, Subprotocol
49-
from .compatibility import loop_if_py_lt_38
49+
from .compatibility import asyncio_timeout, loop_if_py_lt_38
5050
from .handshake import build_response, check_request
5151
from .http import read_request
5252
from .protocol import WebSocketCommonProtocol
@@ -163,15 +163,13 @@ async def handler(self) -> None:
163163
"""
164164
try:
165165
try:
166-
await asyncio.wait_for(
167-
self.handshake(
166+
async with asyncio_timeout(self.open_timeout):
167+
await self.handshake(
168168
origins=self.origins,
169169
available_extensions=self.available_extensions,
170170
available_subprotocols=self.available_subprotocols,
171171
extra_headers=self.extra_headers,
172-
),
173-
self.open_timeout,
174-
)
172+
)
175173
# Remove this branch when dropping support for Python < 3.8
176174
# because CancelledError no longer inherits Exception.
177175
except asyncio.CancelledError: # pragma: no cover

tests/legacy/test_client_server.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
)
3030
from websockets.http import USER_AGENT
3131
from websockets.legacy.client import *
32+
from websockets.legacy.compatibility import asyncio_timeout
3233
from websockets.legacy.handshake import build_response
3334
from websockets.legacy.http import read_response
3435
from websockets.legacy.server import *
@@ -1129,7 +1130,8 @@ def test_client_connect_canceled_during_handshake(self):
11291130

11301131
async def cancelled_client():
11311132
start_client = connect(get_server_uri(self.server), sock=sock)
1132-
await asyncio.wait_for(start_client, 5 * MS)
1133+
async with asyncio_timeout(5 * MS):
1134+
await start_client
11331135

11341136
with self.assertRaises(asyncio.TimeoutError):
11351137
self.loop.run_until_complete(cancelled_client())

0 commit comments

Comments
 (0)