Skip to content

Commit 259f98d

Browse files
Expand tuples to multiple arguments, but not lists
1 parent e4118cd commit 259f98d

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

docs/index.rst

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ environment dictionary. The server can inspect authentication or other headers
9999
to decide if the client is allowed to connect. To reject a client the handler
100100
must return ``False``.
101101

102-
When the client sends an event to the server the appropriate event handler is
103-
invoked with the ``sid`` and the message. The application can define as many
104-
events as needed and associate them with event handlers. An event is defined
105-
simply by a name.
102+
When the client sends an event to the server, the appropriate event handler is
103+
invoked with the ``sid`` and the message, which can be a single or multiple
104+
arguments. The application can define as many events as needed and associate
105+
them with event handlers. An event is defined simply by a name.
106106

107107
When a connection with a client is broken, the ``disconnect`` event is called,
108108
allowing the application to perform cleanup.
@@ -136,10 +136,13 @@ that it will lose the ability to address individual clients.
136136
sio.leave_room(sid, data['room'])
137137

138138
The :func:`socketio.Server.emit` method takes an event name, a message payload
139-
of type ``str``, ``bytes``, ``list`` or ``dict``, and the recipient room. To
140-
address an individual client, the ``sid`` of that client should be given as
141-
room (assuming the application did not alter these initial rooms). To address
142-
all connected clients, the ``room`` argument should be omitted.
139+
of type ``str``, ``bytes``, ``list``, ``dict`` or ``tuple``, and the recipient
140+
room. When sending a ``tuple``, the elements in it need to be of any of the
141+
other four allowed types. The elements of the tuple will be passed as multiple
142+
arguments to the client-side callback function. To address an individual
143+
client, the ``sid`` of that client should be given as room (assuming the
144+
application did not alter these initial rooms). To address all connected
145+
clients, the ``room`` argument should be omitted.
143146

144147
::
145148

socketio/server.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,14 @@ def _emit_internal(self, sid, event, data, namespace=None, id=None):
311311
binary = False # pragma: nocover
312312
else:
313313
binary = None
314+
# tuples are expanded to multiple arguments, everything else is sent
315+
# as a single argument
316+
if isinstance(data, tuple):
317+
data = list(data)
318+
else:
319+
data = [data]
314320
self._send_packet(sid, packet.Packet(packet.EVENT, namespace=namespace,
315-
data=[event, data], id=id,
321+
data=[event] + data, id=id,
316322
binary=binary))
317323

318324
def _send_packet(self, sid, pkt):
@@ -365,10 +371,9 @@ def _handle_event(self, sid, namespace, id, data):
365371
r = self._trigger_event(data[0], namespace, sid, *data[1:])
366372
if id is not None:
367373
# send ACK packet with the response returned by the handler
374+
# tuples are expanded as multiple arguments
368375
if isinstance(r, tuple):
369376
data = list(r)
370-
elif isinstance(r, list):
371-
data = r
372377
else:
373378
data = [r]
374379
if six.PY2 and not self.binary:

tests/test_server.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,20 @@ def test_emit_internal(self, eio):
125125
'2/foo,["my event","my data"]',
126126
binary=False)
127127

128+
def test_emit_internal_with_tuple(self, eio):
129+
s = server.Server()
130+
s._emit_internal('123', 'my event', ('foo', 'bar'), namespace='/foo')
131+
s.eio.send.assert_called_once_with('123',
132+
'2/foo,["my event","foo","bar"]',
133+
binary=False)
134+
135+
def test_emit_internal_with_list(self, eio):
136+
s = server.Server()
137+
s._emit_internal('123', 'my event', ['foo', 'bar'], namespace='/foo')
138+
s.eio.send.assert_called_once_with('123',
139+
'2/foo,["my event",["foo","bar"]]',
140+
binary=False)
141+
128142
def test_emit_internal_with_callback(self, eio):
129143
s = server.Server()
130144
id = s.manager._generate_ack_id('123', '/foo', 'cb')
@@ -304,7 +318,7 @@ def test_handle_event_with_ack_list(self, eio):
304318
s.on('my message', handler)
305319
s._handle_eio_message('123', '21000["my message","a","b","c"]')
306320
handler.assert_called_once_with('123', 'a', 'b', 'c')
307-
s.eio.send.assert_called_once_with('123', '31000[1,"2",true]',
321+
s.eio.send.assert_called_once_with('123', '31000[[1,"2",true]]',
308322
binary=False)
309323

310324
def test_handle_event_with_ack_binary(self, eio):

0 commit comments

Comments
 (0)