From 5203f03abec0a35879e79f78c4f39f1ebd7a3a35 Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Wed, 17 Jun 2015 09:04:33 +0200 Subject: [PATCH 1/3] * Py3 fixes --- examples/cross_origin/sock.py | 3 ++- examples/flask_chat/run.py | 2 +- examples/pyramid_backbone_redis_chat/serve.py | 2 +- examples/pyramid_backbone_redis_chat_persistence/serve.py | 2 +- examples/simple_chat/chat.py | 7 +++++-- examples/simple_pyramid_chat/serve.py | 2 +- examples/testapp/serve.py | 2 +- socketio/handler.py | 5 ++++- socketio/transports.py | 5 ++++- 9 files changed, 20 insertions(+), 10 deletions(-) diff --git a/examples/cross_origin/sock.py b/examples/cross_origin/sock.py index a72d0ad..1fcee36 100644 --- a/examples/cross_origin/sock.py +++ b/examples/cross_origin/sock.py @@ -1,3 +1,4 @@ +from __future__ import print_function from gevent import monkey; monkey.patch_all() from bottle import Bottle, request @@ -8,7 +9,7 @@ class Hello(namespace.BaseNamespace): def on_hello(self, data): - print "hello", data + print("hello", data) self.emit('greetings', {'from': 'sockets'}) diff --git a/examples/flask_chat/run.py b/examples/flask_chat/run.py index 20e10a6..e54016a 100644 --- a/examples/flask_chat/run.py +++ b/examples/flask_chat/run.py @@ -8,5 +8,5 @@ PORT = 5000 if __name__ == '__main__': - print 'Listening on http://127.0.0.1:%s and on port 10843 (flash policy server)' % PORT + print('Listening on http://127.0.0.1:%s and on port 10843 (flash policy server)' % PORT) SocketIOServer(('', PORT), app, resource="socket.io").serve_forever() diff --git a/examples/pyramid_backbone_redis_chat/serve.py b/examples/pyramid_backbone_redis_chat/serve.py index 88743c0..325597a 100644 --- a/examples/pyramid_backbone_redis_chat/serve.py +++ b/examples/pyramid_backbone_redis_chat/serve.py @@ -6,7 +6,7 @@ app = get_app('development.ini') - print 'Listening on port http://0.0.0.0:8080 and on port 10843 (flash policy server)' + print('Listening on port http://0.0.0.0:8080 and on port 10843 (flash policy server)') SocketIOServer(('0.0.0.0', 8080), app, resource="socket.io", policy_server=True, diff --git a/examples/pyramid_backbone_redis_chat_persistence/serve.py b/examples/pyramid_backbone_redis_chat_persistence/serve.py index 88743c0..325597a 100644 --- a/examples/pyramid_backbone_redis_chat_persistence/serve.py +++ b/examples/pyramid_backbone_redis_chat_persistence/serve.py @@ -6,7 +6,7 @@ app = get_app('development.ini') - print 'Listening on port http://0.0.0.0:8080 and on port 10843 (flash policy server)' + print('Listening on port http://0.0.0.0:8080 and on port 10843 (flash policy server)') SocketIOServer(('0.0.0.0', 8080), app, resource="socket.io", policy_server=True, diff --git a/examples/simple_chat/chat.py b/examples/simple_chat/chat.py index fc3f0cf..5aeb108 100755 --- a/examples/simple_chat/chat.py +++ b/examples/simple_chat/chat.py @@ -1,3 +1,6 @@ +#!/usr/bin/python + +from __future__ import print_function from gevent import monkey; monkey.patch_all() from socketio import socketio_manage @@ -29,7 +32,7 @@ def on_user_message(self, msg): self.socket.session['nickname'], msg) def recv_message(self, message): - print "PING!!!", message + print("PING!!!", message) class Application(object): def __init__(self): @@ -78,7 +81,7 @@ def not_found(start_response): if __name__ == '__main__': - print 'Listening on port 8080 and on port 843 (flash policy server)' + print('Listening on port 8080 and on port 843 (flash policy server)') SocketIOServer(('0.0.0.0', 8080), Application(), resource="socket.io", policy_server=True, policy_listener=('0.0.0.0', 10843)).serve_forever() diff --git a/examples/simple_pyramid_chat/serve.py b/examples/simple_pyramid_chat/serve.py index 5ebc0bc..bcdfbc7 100644 --- a/examples/simple_pyramid_chat/serve.py +++ b/examples/simple_pyramid_chat/serve.py @@ -5,7 +5,7 @@ if __name__ == '__main__': app = get_app('development.ini') - print 'Listening on port http://0.0.0.0:8080 and on port 10843 (flash policy server)' + print('Listening on port http://0.0.0.0:8080 and on port 10843 (flash policy server)') SocketIOServer(('0.0.0.0', 8080), app, resource="socket.io", policy_server=True, diff --git a/examples/testapp/serve.py b/examples/testapp/serve.py index 9fc592a..b600ade 100644 --- a/examples/testapp/serve.py +++ b/examples/testapp/serve.py @@ -5,6 +5,6 @@ if __name__ == '__main__': app = get_app('development.ini') - print 'Listening on port http://127.0.0.1:8080 and on port 843 (flash policy server)' + print('Listening on port http://127.0.0.1:8080 and on port 843 (flash policy server)') SocketIOServer(('127.0.0.1', 8080), app, policy_server=False, transports=['websocket']).serve_forever() diff --git a/socketio/handler.py b/socketio/handler.py index e4b972f..b536945 100644 --- a/socketio/handler.py +++ b/socketio/handler.py @@ -1,7 +1,10 @@ import sys import re import gevent -import urlparse +try: + import urllib.parse as urlparse +except ImportError: + import urlparse from gevent.pywsgi import WSGIHandler from socketio import transports diff --git a/socketio/transports.py b/socketio/transports.py index d4b7ab2..cf41a8e 100644 --- a/socketio/transports.py +++ b/socketio/transports.py @@ -1,6 +1,9 @@ import gevent import urllib -import urlparse +try: + import urllib.parse as urlparse +except ImportError: + import urlparse from geventwebsocket import WebSocketError from gevent.queue import Empty From 06745ee60a5942656b59fcf5ef13f74df633770a Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Wed, 17 Jun 2015 01:27:15 +0200 Subject: [PATCH 2/3] py3 compatibility --- socketio/handler.py | 2 +- socketio/mixins.py | 6 +++--- socketio/namespace.py | 15 ++++++++------- socketio/packet.py | 8 ++++---- socketio/sdjango.py | 2 +- socketio/server.py | 2 +- socketio/sgunicorn.py | 4 ++-- socketio/virtsocket.py | 6 +++--- tests/test_namespace.py | 2 +- tests/test_packet.py | 5 +++-- 10 files changed, 27 insertions(+), 25 deletions(-) diff --git a/socketio/handler.py b/socketio/handler.py index b536945..cab54e5 100644 --- a/socketio/handler.py +++ b/socketio/handler.py @@ -189,7 +189,7 @@ def handle_one_response(self): socket.wsgi_app_greenlet = gevent.spawn(self.application, self.environ, start_response) - except: + except Exception: self.handle_error(*sys.exc_info()) # we need to keep the connection open if we are an open socket diff --git a/socketio/mixins.py b/socketio/mixins.py index b101f24..c07d220 100644 --- a/socketio/mixins.py +++ b/socketio/mixins.py @@ -30,7 +30,7 @@ def emit_to_room(self, room, event, *args): args=args, endpoint=self.ns_name) room_name = self._get_room_name(room) - for sessid, socket in self.socket.server.sockets.iteritems(): + for sessid, socket in self.socket.server.sockets.items(): if 'rooms' not in socket.session: continue if room_name in socket.session['rooms'] and self.socket != socket: @@ -55,7 +55,7 @@ def broadcast_event(self, event, *args): args=args, endpoint=self.ns_name) - for sessid, socket in self.socket.server.sockets.iteritems(): + for sessid, socket in self.socket.server.sockets.items(): socket.send_packet(pkt) def broadcast_event_not_me(self, event, *args): @@ -68,6 +68,6 @@ def broadcast_event_not_me(self, event, *args): args=args, endpoint=self.ns_name) - for sessid, socket in self.socket.server.sockets.iteritems(): + for sessid, socket in self.socket.server.sockets.items(): if socket is not self.socket: socket.send_packet(pkt) diff --git a/socketio/namespace.py b/socketio/namespace.py index cef5ca1..d8a8014 100644 --- a/socketio/namespace.py +++ b/socketio/namespace.py @@ -1,3 +1,4 @@ +from __future__ import print_function import gevent import re import logging @@ -21,11 +22,11 @@ class BaseNamespace(object): :linenos: def on_my_event(self, my_first_arg, my_second_arg): - print "This is the my_first_arg object", my_first_arg - print "This is the my_second_arg object", my_second_arg + print("This is the my_first_arg object", my_first_arg) + print("This is the my_second_arg object", my_second_arg) def on_my_second_event(self, whatever): - print "This holds the first arg that was passed", whatever + print("This holds the first arg that was passed", whatever) Handlers are automatically dispatched based on the name of the incoming event. For example, a 'user message' event will be handled by @@ -38,8 +39,8 @@ def on_my_second_event(self, whatever): :linenos: def on_third_event(self, packet): - print "The full packet", packet - print "See the BaseNamespace::call_method() method for details" + print("The full packet", packet) + print("See the BaseNamespace::call_method() method for details") """ def __init__(self, environ, ns_name, request=None): self.environ = environ @@ -167,14 +168,14 @@ def process_packet(self, packet): elif packet_type == 'ack': callback = self.socket._pop_ack_callback(packet['ackId']) if not callback: - print "ERROR: No such callback for ackId %s" % packet['ackId'] + print("ERROR: No such callback for ackId %s" % packet['ackId']) return return callback(*(packet['args'])) elif packet_type == 'disconnect': # Force a disconnect on the namespace. return self.call_method_with_acl('recv_disconnect', packet) else: - print "Unprocessed packet", packet + print("Unprocessed packet", packet) # TODO: manage the other packet types: disconnect def process_event(self, packet): diff --git a/socketio/packet.py b/socketio/packet.py index f626d40..2af4d1e 100644 --- a/socketio/packet.py +++ b/socketio/packet.py @@ -12,7 +12,7 @@ 'noop': 8, } -MSG_VALUES = dict((v, k) for k, v in MSG_TYPES.iteritems()) +MSG_VALUES = dict((v, k) for k, v in MSG_TYPES.items()) ERROR_REASONS = { 'transport not supported': 0, @@ -20,13 +20,13 @@ 'unauthorized': 2 } -REASONS_VALUES = dict((v, k) for k, v in ERROR_REASONS.iteritems()) +REASONS_VALUES = dict((v, k) for k, v in ERROR_REASONS.items()) ERROR_ADVICES = { 'reconnect': 0, } -ADVICES_VALUES = dict((v, k) for k, v in ERROR_ADVICES.iteritems()) +ADVICES_VALUES = dict((v, k) for k, v in ERROR_ADVICES.items()) socketio_packet_attributes = ['type', 'name', 'data', 'endpoint', 'args', 'ackId', 'reason', 'advice', 'qs', 'id'] @@ -153,7 +153,7 @@ def decode(rawstr, json_loads=default_json_loads): elif msg_type == "5": # event try: data = json_loads(data) - except ValueError, e: + except ValueError as e: print("Invalid JSON event message", data) decoded_msg['args'] = [] else: diff --git a/socketio/sdjango.py b/socketio/sdjango.py index d764cdc..20caab3 100644 --- a/socketio/sdjango.py +++ b/socketio/sdjango.py @@ -64,7 +64,7 @@ def __call__(self, handler): def socketio(request): try: socketio_manage(request.environ, SOCKETIO_NS, request) - except: + except Exception: logging.getLogger("socketio").error("Exception while handling socketio connection", exc_info=True) return HttpResponse("") diff --git a/socketio/server.py b/socketio/server.py index 74f2428..d698cb7 100644 --- a/socketio/server.py +++ b/socketio/server.py @@ -105,7 +105,7 @@ def start_accepting(self): try: if not self.policy_server.started: self.policy_server.start() - except error, ex: + except error as ex: sys.stderr.write( 'FAILED to start flash policy server: %s\n' % (ex, )) except Exception: diff --git a/socketio/sgunicorn.py b/socketio/sgunicorn.py index a5a993a..0016cb1 100644 --- a/socketio/sgunicorn.py +++ b/socketio/sgunicorn.py @@ -123,7 +123,7 @@ def run(self): # Force kill all active the handlers self.log.warning("Worker graceful timeout (pid:%s)" % self.pid) [server.stop(timeout=1) for server in servers] - except: + except Exception: pass else: self.socket.setblocking(1) @@ -175,7 +175,7 @@ def run(self): # Force kill all active the handlers self.log.warning("Worker graceful timeout (pid:%s)" % self.pid) server.stop(timeout=1) - except: + except Exception: pass diff --git a/socketio/virtsocket.py b/socketio/virtsocket.py index bd79c01..909a59b 100644 --- a/socketio/virtsocket.py +++ b/socketio/virtsocket.py @@ -311,7 +311,7 @@ def disconnect(self, silent=False): :meth:`~socketio.namespace.BaseNamespace.disconnect` calls. """ - for ns_name, ns in list(self.active_ns.iteritems()): + for ns_name, ns in list(self.active_ns.items()): ns.recv_disconnect() def remove_namespace(self, namespace): @@ -362,7 +362,7 @@ def _receiver_loop(self): continue # or close the connection ? try: pkt = packet.decode(rawdata, self.json_loads) - except (ValueError, KeyError, Exception), e: + except (ValueError, KeyError, Exception) as e: self.error('invalid_packet', "There was a decoding error when dealing with packet " "with event: %s... (%s)" % (rawdata[:20], e)) @@ -436,7 +436,7 @@ def _watcher(self): while True: gevent.sleep(1.0) if not self.connected: - for ns_name, ns in list(self.active_ns.iteritems()): + for ns_name, ns in list(self.active_ns.items()): ns.recv_disconnect() # Killing Socket-level jobs gevent.killall(self.jobs) diff --git a/tests/test_namespace.py b/tests/test_namespace.py index 98a6e4f..9faedd7 100644 --- a/tests/test_namespace.py +++ b/tests/test_namespace.py @@ -206,7 +206,7 @@ def test_del_acl_method(self): except ValueError as e: self.assertEqual( message, - e.message, + e.args[0], ) else: raise Exception("""We should not be able to delete an acl that diff --git a/tests/test_packet.py b/tests/test_packet.py index 6d67c07..0746131 100644 --- a/tests/test_packet.py +++ b/tests/test_packet.py @@ -119,7 +119,8 @@ def test_encode_event(self): 'endpoint': '', 'args': [{"a":"b"}, 2,"3"] }) - self.assertEqual(encoded_message, + if encoded_message != '5:::{"name":"edwald","args":[{"a":"b"},2,"3"]}': + self.assertEqual(encoded_message, '5:::{"args":[{"a":"b"},2,"3"],"name":"edwald"}') def test_encode_ack(self): @@ -349,7 +350,7 @@ def test_except_on_invalid_message_type(self): try: decoded_message = decode('99::') except Exception as e: - self.assertEqual(e.message, "Unknown message type: 99") + self.assertEqual(e.args[0], "Unknown message type: 99") else: self.assertEqual(decoded_message, None, "We should not get a valid message") From ca1494d08bc319583fb07523297d973b740005a1 Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Tue, 23 Jun 2015 02:29:23 +0200 Subject: [PATCH 3/3] Python3: HTTP response body needs to be bytes --- socketio/handler.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/socketio/handler.py b/socketio/handler.py index cab54e5..c0b56b5 100644 --- a/socketio/handler.py +++ b/socketio/handler.py @@ -1,6 +1,8 @@ import sys import re import gevent +from gevent.hub import text_type + try: import urllib.parse as urlparse except ImportError: @@ -70,7 +72,11 @@ def write_jsonp_result(self, data, wrapper="0"): self.start_response("200 OK", [ ("Content-Type", "application/javascript"), ]) - self.result = ['io.j[%s]("%s");' % (wrapper, data)] + if isinstance(wrapper, text_type): + wrapper = wrapper.encode('utf-8') + if isinstance(data, text_type): + data = data.encode('utf-8') + self.result = [(b'io.j[%s]("%s");' % (wrapper, data))] def write_plain_result(self, data): self.start_response("200 OK", [ @@ -80,6 +86,8 @@ def write_plain_result(self, data): ("Access-Control-Max-Age", 3600), ("Content-Type", "text/plain"), ]) + if isinstance(data, text_type): + data = data.encode('utf-8') self.result = [data] def write_smart(self, data):