A pattern that appears in the codebase is to try calling a (dis)connection handler with one set of arguments, and if it raises a TypeError, call again with a different set:
|
try: |
|
success = self._trigger_event( |
|
'connect', namespace, sid, self.environ[eio_sid]) |
|
except TypeError: |
|
success = self._trigger_event( |
|
'connect', namespace, sid, self.environ[eio_sid], None) |
This is risky if the event handler itself can raise a TypeError, unrelated to the handler's arity. This could cause the handler to be run up to the point it throws a TypeError, then the TypeError is consumed and the handler is called again.
A contrived example might be:
@sio.on('connect', namespace='*')
async def on_client_connect(namespace, sid, environ, *args):
initialize_client_state(sid)
2 + "two"
This will be called once with (namespace, sid, environ) and initialize some client state. Then it will raise a TypeError, so it will be called again with (namespace, sid, environ, auth). The client state will be initialized a second time, which might lead to an unexpected state, resource leaks, etc.
It may be better to check inspect.signature(handler).parameters -- however when the event is triggered with self._trigger_event() it doesn't have a reference to the handler callable.
(I'm filing this only because while debugging some other part of my application, I kept getting complaints about including auth or not including auth in my parameter list. Finally I settled on adding *args and moving on.)
A pattern that appears in the codebase is to try calling a (dis)connection handler with one set of arguments, and if it raises a
TypeError, call again with a different set:python-socketio/src/socketio/server.py
Lines 537 to 542 in b01b197
This is risky if the event handler itself can raise a
TypeError, unrelated to the handler's arity. This could cause the handler to be run up to the point it throws aTypeError, then theTypeErroris consumed and the handler is called again.A contrived example might be:
This will be called once with
(namespace, sid, environ)and initialize some client state. Then it will raise aTypeError, so it will be called again with(namespace, sid, environ, auth). The client state will be initialized a second time, which might lead to an unexpected state, resource leaks, etc.It may be better to check
inspect.signature(handler).parameters-- however when the event is triggered withself._trigger_event()it doesn't have a reference to the handler callable.(I'm filing this only because while debugging some other part of my application, I kept getting complaints about including
author not includingauthin my parameter list. Finally I settled on adding*argsand moving on.)