From 6c9b9974f72e2efdf62407ecab24ee6995448098 Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Sun, 16 Nov 2025 13:38:29 +0000 Subject: [PATCH] Support sending bytestrings when using pub/sub managers --- src/socketio/packet.py | 4 ++-- tests/async/test_pubsub_manager.py | 30 +++++++++++++++++++++++++++++ tests/common/test_packet.py | 4 ++++ tests/common/test_pubsub_manager.py | 30 +++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/socketio/packet.py b/src/socketio/packet.py index 3deba7f..101455e 100644 --- a/src/socketio/packet.py +++ b/src/socketio/packet.py @@ -154,7 +154,7 @@ class Packet: @classmethod def _deconstruct_binary_internal(cls, data, attachments): - if isinstance(data, bytes): + if isinstance(data, (bytes, bytearray)): attachments.append(data) return {'_placeholder': True, 'num': len(attachments) - 1} elif isinstance(data, list): @@ -169,7 +169,7 @@ class Packet: @classmethod def data_is_binary(cls, data): """Check if the data contains binary components.""" - if isinstance(data, bytes): + if isinstance(data, (bytes, bytearray)): return True elif isinstance(data, list): return functools.reduce( diff --git a/tests/async/test_pubsub_manager.py b/tests/async/test_pubsub_manager.py index 5d34e53..f9cfb7e 100644 --- a/tests/async/test_pubsub_manager.py +++ b/tests/async/test_pubsub_manager.py @@ -97,6 +97,36 @@ class TestAsyncPubSubManager: } ) + async def test_emit_bytearray(self): + await self.pm.emit('foo', bytearray(b'bar')) + self.pm._publish.assert_awaited_once_with( + { + 'method': 'emit', + 'event': 'foo', + 'binary': True, + 'data': [{'_placeholder': True, 'num': 0}, 'YmFy'], + 'namespace': '/', + 'room': None, + 'skip_sid': None, + 'callback': None, + 'host_id': '123456', + } + ) + await self.pm.emit('foo', {'foo': bytearray(b'bar')}) + self.pm._publish.assert_awaited_with( + { + 'method': 'emit', + 'event': 'foo', + 'binary': True, + 'data': [{'foo': {'_placeholder': True, 'num': 0}}, 'YmFy'], + 'namespace': '/', + 'room': None, + 'skip_sid': None, + 'callback': None, + 'host_id': '123456', + } + ) + async def test_emit_with_to(self): sid = 'room-mate' await self.pm.emit('foo', 'bar', to=sid) diff --git a/tests/common/test_packet.py b/tests/common/test_packet.py index e15babf..e965313 100644 --- a/tests/common/test_packet.py +++ b/tests/common/test_packet.py @@ -279,11 +279,15 @@ class TestPacket: assert not pkt.data_is_binary(['foo']) assert not pkt.data_is_binary([]) assert pkt.data_is_binary([b'foo']) + assert pkt.data_is_binary([bytearray(b'foo')]) assert pkt.data_is_binary(['foo', b'bar']) + assert pkt.data_is_binary(['foo', bytearray(b'bar')]) def test_data_is_binary_dict(self): pkt = packet.Packet() assert not pkt.data_is_binary({'a': 'foo'}) assert not pkt.data_is_binary({}) assert pkt.data_is_binary({'a': b'foo'}) + assert pkt.data_is_binary({'a': bytearray(b'foo')}) assert pkt.data_is_binary({'a': 'foo', 'b': b'bar'}) + assert pkt.data_is_binary({'a': 'foo', 'b': bytearray(b'bar')}) diff --git a/tests/common/test_pubsub_manager.py b/tests/common/test_pubsub_manager.py index 5ef5473..abef2bf 100644 --- a/tests/common/test_pubsub_manager.py +++ b/tests/common/test_pubsub_manager.py @@ -109,6 +109,36 @@ class TestPubSubManager: } ) + def test_emit_bytearray(self): + self.pm.emit('foo', bytearray(b'bar')) + self.pm._publish.assert_called_once_with( + { + 'method': 'emit', + 'event': 'foo', + 'binary': True, + 'data': [{'_placeholder': True, 'num': 0}, 'YmFy'], + 'namespace': '/', + 'room': None, + 'skip_sid': None, + 'callback': None, + 'host_id': '123456', + } + ) + self.pm.emit('foo', {'foo': bytearray(b'bar')}) + self.pm._publish.assert_called_with( + { + 'method': 'emit', + 'event': 'foo', + 'binary': True, + 'data': [{'foo': {'_placeholder': True, 'num': 0}}, 'YmFy'], + 'namespace': '/', + 'room': None, + 'skip_sid': None, + 'callback': None, + 'host_id': '123456', + } + ) + def test_emit_with_to(self): sid = "ferris" self.pm.emit('foo', 'bar', to=sid)