Skip to content

Commit

Permalink
Clarify behavior of recv(timeout=0) behavior.
Browse files Browse the repository at this point in the history
Refs #1552.
  • Loading branch information
mattyoungberg authored and aaugustin committed Jan 11, 2025
1 parent b1e88fc commit 6317c00
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
7 changes: 4 additions & 3 deletions src/websockets/sync/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,10 @@ def recv(self, timeout: float | None = None, decode: bool | None = None) -> Data
message stream.
If ``timeout`` is :obj:`None`, block until a message is received. If
``timeout`` is set and no message is received within ``timeout``
seconds, raise :exc:`TimeoutError`. Set ``timeout`` to ``0`` to check if
a message was already received.
``timeout`` is set, wait up to ``timeout`` seconds for a message to be
received and return it, else raise :exc:`TimeoutError`. If ``timeout``
is ``0`` or negative, check if a message has been received already and
return it, else raise :exc:`TimeoutError`.
If the message is fragmented, wait until all fragments are received,
reassemble them, and return the whole message.
Expand Down
24 changes: 22 additions & 2 deletions tests/sync/test_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,32 @@ def test_get_timeout_after_first_frame(self):
message = self.assembler.get()
self.assertEqual(message, "café")

def test_get_if_received(self):
"""get returns a text message if it's already received."""
def test_get_timeout_0_message_already_received(self):
"""get(timeout=0) returns a message that is already received."""
self.assembler.put(Frame(OP_TEXT, b"caf\xc3\xa9"))
message = self.assembler.get(timeout=0)
self.assertEqual(message, "café")

def test_get_timeout_0_message_not_received_yet(self):
"""get(timeout=0) times out when no message is already received."""
with self.assertRaises(TimeoutError):
self.assembler.get(timeout=0)

def test_get_timeout_0_fragmented_message_already_received(self):
"""get(timeout=0) returns a fragmented message that is already received."""
self.assembler.put(Frame(OP_TEXT, b"ca", fin=False))
self.assembler.put(Frame(OP_CONT, b"f\xc3", fin=False))
self.assembler.put(Frame(OP_CONT, b"\xa9"))
message = self.assembler.get(timeout=0)
self.assertEqual(message, "café")

def test_get_timeout_0_fragmented_message_partially_received(self):
"""get(timeout=0) times out when a fragmented message is partially received."""
self.assembler.put(Frame(OP_TEXT, b"ca", fin=False))
self.assembler.put(Frame(OP_CONT, b"f\xc3", fin=False))
with self.assertRaises(TimeoutError):
self.assembler.get(timeout=0)

# Test get_iter

def test_get_iter_text_message_already_received(self):
Expand Down

0 comments on commit 6317c00

Please sign in to comment.