diff --git a/experiments/compression/benchmark.py b/experiments/compression/benchmark.py index c5b13c8f..4fbdf622 100644 --- a/experiments/compression/benchmark.py +++ b/experiments/compression/benchmark.py @@ -66,7 +66,7 @@ def _run(data): for _ in range(REPEAT): for item in data: if isinstance(item, str): - item = item.encode("utf-8") + item = item.encode() # Taken from PerMessageDeflate.encode item = encoder.compress(item) + encoder.flush(zlib.Z_SYNC_FLUSH) if item.endswith(b"\x00\x00\xff\xff"): diff --git a/src/websockets/frames.py b/src/websockets/frames.py index 6b1befb2..63c35ed4 100644 --- a/src/websockets/frames.py +++ b/src/websockets/frames.py @@ -364,7 +364,7 @@ def prepare_data(data: Data) -> Tuple[int, bytes]: """ if isinstance(data, str): - return OP_TEXT, data.encode("utf-8") + return OP_TEXT, data.encode() elif isinstance(data, BytesLike): return OP_BINARY, data else: @@ -387,7 +387,7 @@ def prepare_ctrl(data: Data) -> bytes: """ if isinstance(data, str): - return data.encode("utf-8") + return data.encode() elif isinstance(data, BytesLike): return bytes(data) else: @@ -456,7 +456,7 @@ def serialize(self) -> bytes: """ self.check() - return struct.pack("!H", self.code) + self.reason.encode("utf-8") + return struct.pack("!H", self.code) + self.reason.encode() def check(self) -> None: """ diff --git a/src/websockets/sync/connection.py b/src/websockets/sync/connection.py index 4a8879e3..62aa17ff 100644 --- a/src/websockets/sync/connection.py +++ b/src/websockets/sync/connection.py @@ -287,7 +287,7 @@ def send(self, message: Union[Data, Iterable[Data]]) -> None: "cannot call send while another thread " "is already running send" ) - self.protocol.send_text(message.encode("utf-8")) + self.protocol.send_text(message.encode()) elif isinstance(message, BytesLike): with self.send_context(): @@ -324,7 +324,7 @@ def send(self, message: Union[Data, Iterable[Data]]) -> None: ) self.send_in_progress = True self.protocol.send_text( - chunk.encode("utf-8"), + chunk.encode(), fin=False, ) elif isinstance(chunk, BytesLike): @@ -349,7 +349,7 @@ def send(self, message: Union[Data, Iterable[Data]]) -> None: with self.send_context(): assert self.send_in_progress self.protocol.send_continuation( - chunk.encode("utf-8"), + chunk.encode(), fin=False, ) elif isinstance(chunk, BytesLike) and not text: @@ -630,7 +630,7 @@ def send_context( socket:: with self.send_context(): - self.protocol.send_text(message.encode("utf-8")) + self.protocol.send_text(message.encode()) When the connection isn't open on entry, when the connection is expected to close on exit, or when an unexpected error happens, terminating the diff --git a/tests/extensions/test_permessage_deflate.py b/tests/extensions/test_permessage_deflate.py index 0e698566..ee09813c 100644 --- a/tests/extensions/test_permessage_deflate.py +++ b/tests/extensions/test_permessage_deflate.py @@ -84,7 +84,7 @@ def test_no_encode_decode_close_frame(self): # Data frames are encoded and decoded. def test_encode_decode_text_frame(self): - frame = Frame(OP_TEXT, "café".encode("utf-8")) + frame = Frame(OP_TEXT, "café".encode()) enc_frame = self.extension.encode(frame) @@ -112,9 +112,9 @@ def test_encode_decode_binary_frame(self): self.assertEqual(dec_frame, frame) def test_encode_decode_fragmented_text_frame(self): - frame1 = Frame(OP_TEXT, "café".encode("utf-8"), fin=False) - frame2 = Frame(OP_CONT, " & ".encode("utf-8"), fin=False) - frame3 = Frame(OP_CONT, "croissants".encode("utf-8")) + frame1 = Frame(OP_TEXT, "café".encode(), fin=False) + frame2 = Frame(OP_CONT, " & ".encode(), fin=False) + frame3 = Frame(OP_CONT, "croissants".encode()) enc_frame1 = self.extension.encode(frame1) enc_frame2 = self.extension.encode(frame2) @@ -168,7 +168,7 @@ def test_encode_decode_fragmented_binary_frame(self): self.assertEqual(dec_frame2, frame2) def test_no_decode_text_frame(self): - frame = Frame(OP_TEXT, "café".encode("utf-8")) + frame = Frame(OP_TEXT, "café".encode()) # Try decoding a frame that wasn't encoded. self.assertEqual(self.extension.decode(frame), frame) @@ -180,9 +180,9 @@ def test_no_decode_binary_frame(self): self.assertEqual(self.extension.decode(frame), frame) def test_no_decode_fragmented_text_frame(self): - frame1 = Frame(OP_TEXT, "café".encode("utf-8"), fin=False) - frame2 = Frame(OP_CONT, " & ".encode("utf-8"), fin=False) - frame3 = Frame(OP_CONT, "croissants".encode("utf-8")) + frame1 = Frame(OP_TEXT, "café".encode(), fin=False) + frame2 = Frame(OP_CONT, " & ".encode(), fin=False) + frame3 = Frame(OP_CONT, "croissants".encode()) dec_frame1 = self.extension.decode(frame1) dec_frame2 = self.extension.decode(frame2) @@ -203,7 +203,7 @@ def test_no_decode_fragmented_binary_frame(self): self.assertEqual(dec_frame2, frame2) def test_context_takeover(self): - frame = Frame(OP_TEXT, "café".encode("utf-8")) + frame = Frame(OP_TEXT, "café".encode()) enc_frame1 = self.extension.encode(frame) enc_frame2 = self.extension.encode(frame) @@ -215,7 +215,7 @@ def test_remote_no_context_takeover(self): # No context takeover when decoding messages. self.extension = PerMessageDeflate(True, False, 15, 15) - frame = Frame(OP_TEXT, "café".encode("utf-8")) + frame = Frame(OP_TEXT, "café".encode()) enc_frame1 = self.extension.encode(frame) enc_frame2 = self.extension.encode(frame) @@ -233,7 +233,7 @@ def test_local_no_context_takeover(self): # No context takeover when encoding and decoding messages. self.extension = PerMessageDeflate(True, True, 15, 15) - frame = Frame(OP_TEXT, "café".encode("utf-8")) + frame = Frame(OP_TEXT, "café".encode()) enc_frame1 = self.extension.encode(frame) enc_frame2 = self.extension.encode(frame) @@ -253,7 +253,7 @@ def test_compress_settings(self): # Configure an extension so that no compression actually occurs. extension = PerMessageDeflate(False, False, 15, 15, {"level": 0}) - frame = Frame(OP_TEXT, "café".encode("utf-8")) + frame = Frame(OP_TEXT, "café".encode()) enc_frame = extension.encode(frame) @@ -269,7 +269,7 @@ def test_compress_settings(self): # Frames aren't decoded beyond max_size. def test_decompress_max_size(self): - frame = Frame(OP_TEXT, ("a" * 20).encode("utf-8")) + frame = Frame(OP_TEXT, ("a" * 20).encode()) enc_frame = self.extension.encode(frame) diff --git a/tests/legacy/test_framing.py b/tests/legacy/test_framing.py index e1e4c891..6f811bd5 100644 --- a/tests/legacy/test_framing.py +++ b/tests/legacy/test_framing.py @@ -76,14 +76,12 @@ def test_binary_masked(self): ) def test_non_ascii_text(self): - self.round_trip( - b"\x81\x05caf\xc3\xa9", Frame(True, OP_TEXT, "café".encode("utf-8")) - ) + self.round_trip(b"\x81\x05caf\xc3\xa9", Frame(True, OP_TEXT, "café".encode())) def test_non_ascii_text_masked(self): self.round_trip( b"\x81\x85\x64\xbe\xee\x7e\x07\xdf\x88\xbd\xcd", - Frame(True, OP_TEXT, "café".encode("utf-8")), + Frame(True, OP_TEXT, "café".encode()), mask=True, ) diff --git a/tests/legacy/test_protocol.py b/tests/legacy/test_protocol.py index f2eb0fea..f3dcd9ac 100644 --- a/tests/legacy/test_protocol.py +++ b/tests/legacy/test_protocol.py @@ -428,7 +428,7 @@ def test_close_reason_not_set(self): # Test the recv coroutine. def test_recv_text(self): - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "café".encode())) data = self.loop.run_until_complete(self.protocol.recv()) self.assertEqual(data, "café") @@ -458,7 +458,7 @@ def test_recv_on_closed_connection(self): self.loop.run_until_complete(self.protocol.recv()) def test_recv_protocol_error(self): - self.receive_frame(Frame(True, OP_CONT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_CONT, "café".encode())) self.process_invalid_frames() self.assertConnectionFailed(CloseCode.PROTOCOL_ERROR, "") @@ -469,7 +469,7 @@ def test_recv_unicode_error(self): def test_recv_text_payload_too_big(self): self.protocol.max_size = 1024 - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8") * 205)) + self.receive_frame(Frame(True, OP_TEXT, "café".encode() * 205)) self.process_invalid_frames() self.assertConnectionFailed(CloseCode.MESSAGE_TOO_BIG, "") @@ -481,7 +481,7 @@ def test_recv_binary_payload_too_big(self): def test_recv_text_no_max_size(self): self.protocol.max_size = None # for test coverage - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8") * 205)) + self.receive_frame(Frame(True, OP_TEXT, "café".encode() * 205)) data = self.loop.run_until_complete(self.protocol.recv()) self.assertEqual(data, "café" * 205) @@ -498,7 +498,7 @@ def test_recv_queue_empty(self): asyncio.wait_for(asyncio.shield(recv), timeout=MS) ) - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "café".encode())) data = self.loop.run_until_complete(recv) self.assertEqual(data, "café") @@ -507,7 +507,7 @@ def test_recv_queue_full(self): # Test internals because it's hard to verify buffers from the outside. self.assertEqual(list(self.protocol.messages), []) - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "café".encode())) self.run_loop_once() self.assertEqual(list(self.protocol.messages), ["café"]) @@ -535,7 +535,7 @@ def test_recv_queue_no_limit(self): self.protocol.max_queue = None for _ in range(100): - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "café".encode())) self.run_loop_once() # Incoming message queue can contain at least 100 messages. @@ -562,7 +562,7 @@ def test_recv_canceled(self): self.loop.run_until_complete(recv) # The next frame doesn't disappear in a vacuum (it used to). - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "café".encode())) data = self.loop.run_until_complete(self.protocol.recv()) self.assertEqual(data, "café") @@ -570,15 +570,13 @@ def test_recv_canceled_race_condition(self): recv = self.loop.create_task( asyncio.wait_for(self.protocol.recv(), timeout=0.000_001) ) - self.loop.call_soon( - self.receive_frame, Frame(True, OP_TEXT, "café".encode("utf-8")) - ) + self.loop.call_soon(self.receive_frame, Frame(True, OP_TEXT, "café".encode())) with self.assertRaises(asyncio.TimeoutError): self.loop.run_until_complete(recv) # The previous frame doesn't disappear in a vacuum (it used to). - self.receive_frame(Frame(True, OP_TEXT, "tea".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "tea".encode())) data = self.loop.run_until_complete(self.protocol.recv()) # If we're getting "tea" there, it means "café" was swallowed (ha, ha). self.assertEqual(data, "café") @@ -586,7 +584,7 @@ def test_recv_canceled_race_condition(self): def test_recv_when_transfer_data_cancelled(self): # Clog incoming queue. self.protocol.max_queue = 1 - self.receive_frame(Frame(True, OP_TEXT, "café".encode("utf-8"))) + self.receive_frame(Frame(True, OP_TEXT, "café".encode())) self.receive_frame(Frame(True, OP_BINARY, b"tea")) self.run_loop_once() @@ -620,7 +618,7 @@ def test_recv_prevents_concurrent_calls(self): def test_send_text(self): self.loop.run_until_complete(self.protocol.send("café")) - self.assertOneFrameSent(True, OP_TEXT, "café".encode("utf-8")) + self.assertOneFrameSent(True, OP_TEXT, "café".encode()) def test_send_binary(self): self.loop.run_until_complete(self.protocol.send(b"tea")) @@ -647,9 +645,9 @@ def test_send_type_error(self): def test_send_iterable_text(self): self.loop.run_until_complete(self.protocol.send(["ca", "fé"])) self.assertFramesSent( - (False, OP_TEXT, "ca".encode("utf-8")), - (False, OP_CONT, "fé".encode("utf-8")), - (True, OP_CONT, "".encode("utf-8")), + (False, OP_TEXT, "ca".encode()), + (False, OP_CONT, "fé".encode()), + (True, OP_CONT, "".encode()), ) def test_send_iterable_binary(self): @@ -687,7 +685,7 @@ def test_send_iterable_mixed_type_error(self): with self.assertRaises(TypeError): self.loop.run_until_complete(self.protocol.send(["café", b"tea"])) self.assertFramesSent( - (False, OP_TEXT, "café".encode("utf-8")), + (False, OP_TEXT, "café".encode()), (True, OP_CLOSE, Close(CloseCode.INTERNAL_ERROR, "").serialize()), ) @@ -710,18 +708,18 @@ async def run_concurrently(): self.loop.run_until_complete(run_concurrently()) self.assertFramesSent( - (False, OP_TEXT, "ca".encode("utf-8")), - (False, OP_CONT, "fé".encode("utf-8")), - (True, OP_CONT, "".encode("utf-8")), + (False, OP_TEXT, "ca".encode()), + (False, OP_CONT, "fé".encode()), + (True, OP_CONT, "".encode()), (True, OP_BINARY, b"tea"), ) def test_send_async_iterable_text(self): self.loop.run_until_complete(self.protocol.send(async_iterable(["ca", "fé"]))) self.assertFramesSent( - (False, OP_TEXT, "ca".encode("utf-8")), - (False, OP_CONT, "fé".encode("utf-8")), - (True, OP_CONT, "".encode("utf-8")), + (False, OP_TEXT, "ca".encode()), + (False, OP_CONT, "fé".encode()), + (True, OP_CONT, "".encode()), ) def test_send_async_iterable_binary(self): @@ -761,7 +759,7 @@ def test_send_async_iterable_mixed_type_error(self): self.protocol.send(async_iterable(["café", b"tea"])) ) self.assertFramesSent( - (False, OP_TEXT, "café".encode("utf-8")), + (False, OP_TEXT, "café".encode()), (True, OP_CLOSE, Close(CloseCode.INTERNAL_ERROR, "").serialize()), ) @@ -784,9 +782,9 @@ async def run_concurrently(): self.loop.run_until_complete(run_concurrently()) self.assertFramesSent( - (False, OP_TEXT, "ca".encode("utf-8")), - (False, OP_CONT, "fé".encode("utf-8")), - (True, OP_CONT, "".encode("utf-8")), + (False, OP_TEXT, "ca".encode()), + (False, OP_CONT, "fé".encode()), + (True, OP_CONT, "".encode()), (True, OP_BINARY, b"tea"), ) @@ -829,7 +827,7 @@ def test_ping_default(self): def test_ping_text(self): self.loop.run_until_complete(self.protocol.ping("café")) - self.assertOneFrameSent(True, OP_PING, "café".encode("utf-8")) + self.assertOneFrameSent(True, OP_PING, "café".encode()) def test_ping_binary(self): self.loop.run_until_complete(self.protocol.ping(b"tea")) @@ -882,7 +880,7 @@ def test_pong_default(self): def test_pong_text(self): self.loop.run_until_complete(self.protocol.pong("café")) - self.assertOneFrameSent(True, OP_PONG, "café".encode("utf-8")) + self.assertOneFrameSent(True, OP_PONG, "café".encode()) def test_pong_binary(self): self.loop.run_until_complete(self.protocol.pong(b"tea")) @@ -1072,8 +1070,8 @@ def test_return_latency_on_pong(self): # Test the protocol's logic for rebuilding fragmented messages. def test_fragmented_text(self): - self.receive_frame(Frame(False, OP_TEXT, "ca".encode("utf-8"))) - self.receive_frame(Frame(True, OP_CONT, "fé".encode("utf-8"))) + self.receive_frame(Frame(False, OP_TEXT, "ca".encode())) + self.receive_frame(Frame(True, OP_CONT, "fé".encode())) data = self.loop.run_until_complete(self.protocol.recv()) self.assertEqual(data, "café") @@ -1086,8 +1084,8 @@ def test_fragmented_binary(self): def test_fragmented_text_payload_too_big(self): self.protocol.max_size = 1024 - self.receive_frame(Frame(False, OP_TEXT, "café".encode("utf-8") * 100)) - self.receive_frame(Frame(True, OP_CONT, "café".encode("utf-8") * 105)) + self.receive_frame(Frame(False, OP_TEXT, "café".encode() * 100)) + self.receive_frame(Frame(True, OP_CONT, "café".encode() * 105)) self.process_invalid_frames() self.assertConnectionFailed(CloseCode.MESSAGE_TOO_BIG, "") @@ -1100,8 +1098,8 @@ def test_fragmented_binary_payload_too_big(self): def test_fragmented_text_no_max_size(self): self.protocol.max_size = None # for test coverage - self.receive_frame(Frame(False, OP_TEXT, "café".encode("utf-8") * 100)) - self.receive_frame(Frame(True, OP_CONT, "café".encode("utf-8") * 105)) + self.receive_frame(Frame(False, OP_TEXT, "café".encode() * 100)) + self.receive_frame(Frame(True, OP_CONT, "café".encode() * 105)) data = self.loop.run_until_complete(self.protocol.recv()) self.assertEqual(data, "café" * 205) @@ -1113,22 +1111,22 @@ def test_fragmented_binary_no_max_size(self): self.assertEqual(data, b"tea" * 342) def test_control_frame_within_fragmented_text(self): - self.receive_frame(Frame(False, OP_TEXT, "ca".encode("utf-8"))) + self.receive_frame(Frame(False, OP_TEXT, "ca".encode())) self.receive_frame(Frame(True, OP_PING, b"")) - self.receive_frame(Frame(True, OP_CONT, "fé".encode("utf-8"))) + self.receive_frame(Frame(True, OP_CONT, "fé".encode())) data = self.loop.run_until_complete(self.protocol.recv()) self.assertEqual(data, "café") self.assertOneFrameSent(True, OP_PONG, b"") def test_unterminated_fragmented_text(self): - self.receive_frame(Frame(False, OP_TEXT, "ca".encode("utf-8"))) + self.receive_frame(Frame(False, OP_TEXT, "ca".encode())) # Missing the second part of the fragmented frame. self.receive_frame(Frame(True, OP_BINARY, b"tea")) self.process_invalid_frames() self.assertConnectionFailed(CloseCode.PROTOCOL_ERROR, "") def test_close_handshake_in_fragmented_text(self): - self.receive_frame(Frame(False, OP_TEXT, "ca".encode("utf-8"))) + self.receive_frame(Frame(False, OP_TEXT, "ca".encode())) self.receive_frame(Frame(True, OP_CLOSE, b"")) self.process_invalid_frames() # The RFC may have overlooked this case: it says that control frames @@ -1138,7 +1136,7 @@ def test_close_handshake_in_fragmented_text(self): self.assertConnectionClosed(CloseCode.NO_STATUS_RCVD, "") def test_connection_close_in_fragmented_text(self): - self.receive_frame(Frame(False, OP_TEXT, "ca".encode("utf-8"))) + self.receive_frame(Frame(False, OP_TEXT, "ca".encode())) self.process_invalid_frames() self.assertConnectionFailed(CloseCode.ABNORMAL_CLOSURE, "") @@ -1472,7 +1470,7 @@ def test_remote_close_during_send(self): def test_broadcast_text(self): broadcast([self.protocol], "café") - self.assertOneFrameSent(True, OP_TEXT, "café".encode("utf-8")) + self.assertOneFrameSent(True, OP_TEXT, "café".encode()) def test_broadcast_binary(self): broadcast([self.protocol], b"tea") @@ -1489,8 +1487,8 @@ def test_broadcast_no_clients(self): def test_broadcast_two_clients(self): broadcast([self.protocol, self.protocol], "café") self.assertFramesSent( - (True, OP_TEXT, "café".encode("utf-8")), - (True, OP_TEXT, "café".encode("utf-8")), + (True, OP_TEXT, "café".encode()), + (True, OP_TEXT, "café".encode()), ) def test_broadcast_skips_closed_connection(self): @@ -1513,7 +1511,7 @@ def test_broadcast_skips_connection_sending_fragmented_text(self): self.make_drain_slow() self.loop.create_task(self.protocol.send(["ca", "fé"])) self.run_loop_once() - self.assertOneFrameSent(False, OP_TEXT, "ca".encode("utf-8")) + self.assertOneFrameSent(False, OP_TEXT, "ca".encode()) with self.assertLogs("websockets", logging.WARNING) as logs: broadcast([self.protocol], "café") @@ -1530,7 +1528,7 @@ def test_broadcast_reports_connection_sending_fragmented_text(self): self.make_drain_slow() self.loop.create_task(self.protocol.send(["ca", "fé"])) self.run_loop_once() - self.assertOneFrameSent(False, OP_TEXT, "ca".encode("utf-8")) + self.assertOneFrameSent(False, OP_TEXT, "ca".encode()) with self.assertRaises(ExceptionGroup) as raised: broadcast([self.protocol], "café", raise_exceptions=True) diff --git a/tests/test_frames.py b/tests/test_frames.py index e323b3b5..3e9f5d6f 100644 --- a/tests/test_frames.py +++ b/tests/test_frames.py @@ -77,14 +77,14 @@ def test_binary_masked(self): def test_non_ascii_text_unmasked(self): self.assertFrameData( - Frame(OP_TEXT, "café".encode("utf-8")), + Frame(OP_TEXT, "café".encode()), b"\x81\x05caf\xc3\xa9", mask=False, ) def test_non_ascii_text_masked(self): self.assertFrameData( - Frame(OP_TEXT, "café".encode("utf-8")), + Frame(OP_TEXT, "café".encode()), b"\x81\x85\x64\xbe\xee\x7e\x07\xdf\x88\xbd\xcd", mask=True, )