Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-python-socketio for
openSUSE:Factory checked in at 2022-01-24 23:10:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-socketio (Old)
and /work/SRC/openSUSE:Factory/.python-python-socketio.new.1938 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-socketio"
Mon Jan 24 23:10:12 2022 rev:5 rq:948409 version:5.5.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-python-socketio/python-python-socketio.changes
2021-10-26 20:14:22.950031635 +0200
+++
/work/SRC/openSUSE:Factory/.python-python-socketio.new.1938/python-python-socketio.changes
2022-01-24 23:10:49.614416413 +0100
@@ -1,0 +2,19 @@
+Sun Jan 23 08:34:21 UTC 2022 - Axel Braun <[email protected]>
+
+- version 5.5.1
+ * Support multiple Kafka servers (thanks sparkingdark!)
+ * Include example code in flake8 pass
+ * Option to disable the SIGINT handler in the client #792
+ * Do not invoke reserved events on a catch-all handler #814
+ * Use correct binary packet types in the msgpack packet encoder #811
+ * Add missing call() method to namespace classes #800
+ * Add missing to argument to namespace emit() and send() methods #810
+ * Configure Redis pubsub to skip subscription messages
+ * Migrate async Redis client manager to aioredis 2 #771 (thanks Sam Mosleh!)
+ * Update Python supported versions in docs
+ * Document how to get the connection state in the client #799
+ * Improved documentation of start_background_task() function
+ * Improved documentation of call() method #813
+ * Fixed intermittent test failures #572
+
+-------------------------------------------------------------------
@@ -5,2 +24,2 @@
- * Catch-all event handlers (commit)
- * Implement disconnect method for external processes #684 (commit)
+ * Catch-all event handlers
+ * Implement disconnect method for external processes #684
Old:
----
python-socketio-5.4.1.tar.gz
New:
----
python-socketio-5.5.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-socketio.spec ++++++
--- /var/tmp/diff_new_pack.s3Snih/_old 2022-01-24 23:10:50.090413160 +0100
+++ /var/tmp/diff_new_pack.s3Snih/_new 2022-01-24 23:10:50.094413133 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-python-socketio
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python3-%{**}}
%define skip_python2 1
Name: python-python-socketio
-Version: 5.4.1
+Version: 5.5.1
Release: 0
Summary: SocketIO server
License: MIT
++++++ python-socketio-5.4.1.tar.gz -> python-socketio-5.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/CHANGES.md
new/python-socketio-5.5.1/CHANGES.md
--- old/python-socketio-5.4.1/CHANGES.md 2021-10-14 21:19:50.000000000
+0200
+++ new/python-socketio-5.5.1/CHANGES.md 2022-01-11 13:17:25.000000000
+0100
@@ -1,5 +1,25 @@
# python-socketio change log
+**Release 5.5.1** - 2022-01-11
+
+- Support multiple Kafka servers
([commit](https://github.com/miguelgrinberg/python-socketio/commit/4ee3649514b98c50cc0bf70d3f269389da52772d))
(thanks **sparkingdark**!)
+- Include example code in flake8 pass
([commit](https://github.com/miguelgrinberg/python-socketio/commit/273a4b0439c84560d403662d8eba4122c28ba0d8))
+
+**Release 5.5.0** - 2021-11-14
+
+- Option to disable the SIGINT handler in the client
[#792](https://github.com/miguelgrinberg/python-socketio/issues/792)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/ea84b9b1c714b02eaf1081f4e37fd130a3159d8c))
+- Do not invoke reserved events on a catch-all handler
[#814](https://github.com/miguelgrinberg/python-socketio/issues/814)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/34f34e53d650dde605f5f4a98d7a70936524a1b8))
+- Use correct binary packet types in the msgpack packet encoder
[#811](https://github.com/miguelgrinberg/python-socketio/issues/811)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/60735dd4c2fc87ed863d7dbf7de361500d963dd3))
+- Add missing `call()` method to namespace classes
[#800](https://github.com/miguelgrinberg/python-socketio/issues/800)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/32db48d12ceb44d7a02fd9f05047b47c7ed3f4a5))
+- Add missing `to` argument to namespace `emit()` and `send()` methods
[#810](https://github.com/miguelgrinberg/python-socketio/issues/810)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/ed08a01e65635160923f3d6d5755df74d53274e1))
+- Configure Redis pubsub to skip subscription messages
([commit](https://github.com/miguelgrinberg/python-socketio/commit/e8fff07b367929794e5e30cecbf252b72d307c16))
+- Migrate async Redis client manager to aioredis 2
[#771](https://github.com/miguelgrinberg/python-socketio/issues/771)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/f245191d86722244a2d3d0529d9f5ff15dfd817a))
(thanks **Sam Mosleh**!)
+- Update Python supported versions in docs
([commit](https://github.com/miguelgrinberg/python-socketio/commit/a54152f2466bad4869d9cfdad6be3a5547e0b6bc))
+- Document how to get the connection state in the client
[#799](https://github.com/miguelgrinberg/python-socketio/issues/799)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/47c5f45c765ae207f58ba2675f91eaf8c79f8500))
+- Improved documentation of `start_background_task()` function
([commit](https://github.com/miguelgrinberg/python-socketio/commit/4f5bf1e9898154aa1a9896a7016ba22bfb73cdf2))
+- Improved documentation of `call()` method
[#813](https://github.com/miguelgrinberg/python-socketio/issues/813)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/8c2a6ac86972bf94acafe687d2e86bdf65119960))
+- Fixed intermittent test failures
[#572](https://github.com/miguelgrinberg/python-socketio/issues/572)
([commit](https://github.com/miguelgrinberg/python-socketio/commit/db0565ada6c8891be3230bcc415e5465bd409c09))
+
**Release 5.4.1** - 2021-10-14
- Catch-all event handlers
([commit](https://github.com/miguelgrinberg/python-socketio/commit/28569d48ad74d5414a0d2a8f69d7540dbdddf066))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/docs/api.rst
new/python-socketio-5.5.1/docs/api.rst
--- old/python-socketio-5.4.1/docs/api.rst 2021-10-14 21:19:50.000000000
+0200
+++ new/python-socketio-5.5.1/docs/api.rst 2022-01-11 13:17:25.000000000
+0100
@@ -35,7 +35,7 @@
``ConnectionRefusedError`` class
--------------------------------
-.. autoclass:: ConnectionRefusedError
+.. autoclass:: socketio.exceptions.ConnectionRefusedError
:members:
``WSGIApp`` class
@@ -128,7 +128,7 @@
:members:
``AsyncAioPikaManager`` class
----------------------------
+-----------------------------
.. autoclass:: AsyncAioPikaManager
:members:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/docs/client.rst
new/python-socketio-5.5.1/docs/client.rst
--- old/python-socketio-5.4.1/docs/client.rst 2021-10-14 21:19:50.000000000
+0200
+++ new/python-socketio-5.5.1/docs/client.rst 2022-01-11 13:17:25.000000000
+0100
@@ -65,6 +65,9 @@
async def message(data):
print('I received a message!')
+If the server includes arguments with an event, those are passed to the
+handler function as arguments.
+
Catch-All Event Handlers
------------------------
@@ -72,13 +75,13 @@
event handler. You can define a catch-all handler using ``'*'`` as event name::
@sio.on('*')
- def catch_all(event, sid, data):
+ def catch_all(event, data):
pass
Asyncio clients can also use a coroutine::
@sio.on('*')
- async def catch_all(event, sid, data):
+ async def catch_all(event, data):
pass
A catch-all event handler receives the event name as a first argument. The
@@ -115,8 +118,8 @@
handler. As soon as the connection is re-established the connect handler will
be invoked once again.
-If the server includes arguments with an event, those are passed to the
-handler function as arguments.
+The ``connect``, ``connect_error`` and ``disconnect`` events have to be
+defined explicitly and are not invoked on a catch-all event handler.
Connecting to a Server
----------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/docs/intro.rst
new/python-socketio-5.5.1/docs/intro.rst
--- old/python-socketio-5.4.1/docs/intro.rst 2021-10-14 21:19:50.000000000
+0200
+++ new/python-socketio-5.5.1/docs/intro.rst 2022-01-11 13:17:25.000000000
+0100
@@ -103,7 +103,7 @@
- Can connect to other Socket.IO servers that are compatible with the
JavaScript Socket.IO 1.x and 2.x releases. Work to support release 3.x is in
progress.
-- Compatible with Python 3.5+.
+- Compatible with Python 3.6+.
- Two versions of the client, one for standard Python and another for
asyncio.
- Uses an event-based architecture implemented with decorators that
@@ -183,7 +183,7 @@
- Can connect to servers running other Socket.IO clients that are compatible
with the JavaScript client versions 1.x and 2.x. Work to support the 3.x
release is in progress.
-- Compatible with Python 3.5+.
+- Compatible with Python 3.6+.
- Two versions of the server, one for standard Python and another for
asyncio.
- Supports large number of clients even on modest hardware due to being
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/docs/server.rst
new/python-socketio-5.5.1/docs/server.rst
--- old/python-socketio-5.4.1/docs/server.rst 2021-10-14 21:19:50.000000000
+0200
+++ new/python-socketio-5.5.1/docs/server.rst 2022-01-11 13:17:25.000000000
+0100
@@ -197,6 +197,9 @@
A catch-all event handler receives the event name as a first argument. The
remaining arguments are the same as for a regular event handler.
+The ``connect`` and ``disconnect`` events have to be defined explicitly and are
+not invoked on a catch-all event handler.
+
Connect and Disconnect Event Handlers
-------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/examples/server/aiohttp/app.py
new/python-socketio-5.5.1/examples/server/aiohttp/app.py
--- old/python-socketio-5.4.1/examples/server/aiohttp/app.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/examples/server/aiohttp/app.py 2022-01-11
13:17:25.000000000 +0100
@@ -1,5 +1,3 @@
-import asyncio
-
from aiohttp import web
import socketio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/examples/server/asgi/app.py
new/python-socketio-5.5.1/examples/server/asgi/app.py
--- old/python-socketio-5.4.1/examples/server/asgi/app.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/examples/server/asgi/app.py 2022-01-11
13:17:25.000000000 +0100
@@ -1,6 +1,4 @@
#!/usr/bin/env python
-import asyncio
-
import uvicorn
import socketio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/examples/server/sanic/app.py
new/python-socketio-5.5.1/examples/server/sanic/app.py
--- old/python-socketio-5.4.1/examples/server/sanic/app.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/examples/server/sanic/app.py 2022-01-11
13:17:25.000000000 +0100
@@ -1,5 +1,3 @@
-import asyncio
-
from sanic import Sanic
from sanic.response import html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/examples/server/tornado/app.py
new/python-socketio-5.5.1/examples/server/tornado/app.py
--- old/python-socketio-5.4.1/examples/server/tornado/app.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/examples/server/tornado/app.py 2022-01-11
13:17:25.000000000 +0100
@@ -42,6 +42,7 @@
await sio.emit('my_response', {'data': 'Entered room: ' + message['room']},
room=sid)
+
@sio.event
async def leave(sid, message):
sio.leave_room(sid, message['room'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/examples/server/wsgi/app.py
new/python-socketio-5.5.1/examples/server/wsgi/app.py
--- old/python-socketio-5.4.1/examples/server/wsgi/app.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/examples/server/wsgi/app.py 2022-01-11
13:17:25.000000000 +0100
@@ -3,7 +3,6 @@
# installed
async_mode = None
-import time
from flask import Flask, render_template
import socketio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/examples/server/wsgi/django_example/django_example/settings.py
new/python-socketio-5.5.1/examples/server/wsgi/django_example/django_example/settings.py
---
old/python-socketio-5.4.1/examples/server/wsgi/django_example/django_example/settings.py
2021-10-14 21:19:50.000000000 +0200
+++
new/python-socketio-5.5.1/examples/server/wsgi/django_example/django_example/settings.py
2022-01-11 13:17:25.000000000 +0100
@@ -1,3 +1,4 @@
+# flake8: noqa
"""
Django settings for django_example project.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/examples/server/wsgi/django_example/manage.py
new/python-socketio-5.5.1/examples/server/wsgi/django_example/manage.py
--- old/python-socketio-5.4.1/examples/server/wsgi/django_example/manage.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/examples/server/wsgi/django_example/manage.py
2022-01-11 13:17:25.000000000 +0100
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# flake8: noqa
import os
import sys
@@ -11,7 +12,7 @@
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
- import django
+ import django # pragma: F401
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/admin.py
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/admin.py
---
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/admin.py
2021-10-14 21:19:50.000000000 +0200
+++
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/admin.py
2022-01-11 13:17:25.000000000 +0100
@@ -1,3 +1,4 @@
+# flake8: noqa
from django.contrib import admin
# Register your models here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/models.py
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/models.py
---
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/models.py
2021-10-14 21:19:50.000000000 +0200
+++
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/models.py
2022-01-11 13:17:25.000000000 +0100
@@ -1,3 +1,4 @@
+# flake8: noqa
from django.db import models
# Create your models here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/tests.py
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/tests.py
---
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/tests.py
2021-10-14 21:19:50.000000000 +0200
+++
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/tests.py
2022-01-11 13:17:25.000000000 +0100
@@ -1,3 +1,4 @@
+# flake8: noqa
from django.test import TestCase
# Create your tests here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/views.py
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/views.py
---
old/python-socketio-5.4.1/examples/server/wsgi/django_example/socketio_app/views.py
2021-10-14 21:19:50.000000000 +0200
+++
new/python-socketio-5.5.1/examples/server/wsgi/django_example/socketio_app/views.py
2022-01-11 13:17:25.000000000 +0100
@@ -80,4 +80,3 @@
@sio.event
def disconnect(sid):
print('Client disconnected')
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/setup.cfg
new/python-socketio-5.5.1/setup.cfg
--- old/python-socketio-5.4.1/setup.cfg 2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/setup.cfg 2022-01-11 13:17:25.000000000 +0100
@@ -1,6 +1,6 @@
[metadata]
name = python-socketio
-version = 5.4.1
+version = 5.5.1
author = Miguel Grinberg
author_email = [email protected]
description = Socket.IO server and client for Python
@@ -25,7 +25,7 @@
python_requires = >=3.6
install_requires =
bidict >= 0.21.0
- python-engineio >= 4.1.0
+ python-engineio >= 4.3.0
[options.packages.find]
where = src
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/src/socketio/asyncio_aiopika_manager.py
new/python-socketio-5.5.1/src/socketio/asyncio_aiopika_manager.py
--- old/python-socketio-5.4.1/src/socketio/asyncio_aiopika_manager.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/asyncio_aiopika_manager.py
2022-01-11 13:17:25.000000000 +0100
@@ -94,7 +94,7 @@
async with self.listener_queue.iterator() as queue_iter:
async for message in queue_iter:
with message.process():
- return pickle.loads(message.body)
+ yield pickle.loads(message.body)
except Exception:
self._get_logger().error('Cannot receive from rabbitmq... '
'retrying in '
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/asyncio_client.py
new/python-socketio-5.5.1/src/socketio/asyncio_client.py
--- old/python-socketio-5.4.1/src/socketio/asyncio_client.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/asyncio_client.py 2022-01-11
13:17:25.000000000 +0100
@@ -40,6 +40,11 @@
packets. Custom json modules must have ``dumps`` and ``loads``
functions that are compatible with the standard library
versions.
+ :param handle_sigint: Set to ``True`` to automatically handle disconnection
+ when the process is interrupted, or to ``False`` to
+ leave interrupt handling to the calling application.
+ Interrupt handling can only be enabled when the
+ client instance is created in the main thread.
The Engine.IO configuration supports the following settings:
@@ -249,6 +254,12 @@
async def call(self, event, data=None, namespace=None, timeout=60):
"""Emit a custom event to a client and wait for the response.
+ This method issues an emit with a callback and waits for the callback
+ to be invoked before returning. If the callback isn't invoked before
+ the timeout, then a ``TimeoutError`` exception is raised. If the
+ Socket.IO connection drops during the wait, this method still waits
+ until the specified timeout.
+
:param event: The event name. It can be any string. The event names
``'connect'``, ``'message'`` and ``'disconnect'`` are
reserved and should not be used.
@@ -311,9 +322,7 @@
:param args: arguments to pass to the function.
:param kwargs: keyword arguments to pass to the function.
- This function returns an object compatible with the `Thread` class in
- the Python standard library. The `start()` method on this object is
- already called by this function.
+ The return value is a ``asyncio.Task`` object.
"""
return self.eio.start_background_task(target, *args, **kwargs)
@@ -422,7 +431,8 @@
handler = None
if event in self.handlers[namespace]:
handler = self.handlers[namespace][event]
- elif '*' in self.handlers[namespace]:
+ elif event not in self.reserved_events and \
+ '*' in self.handlers[namespace]:
handler = self.handlers[namespace]['*']
args = (event, *args)
if handler:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/src/socketio/asyncio_namespace.py
new/python-socketio-5.5.1/src/socketio/asyncio_namespace.py
--- old/python-socketio-5.4.1/src/socketio/asyncio_namespace.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/asyncio_namespace.py 2022-01-11
13:17:25.000000000 +0100
@@ -41,7 +41,7 @@
ret = handler(*args)
return ret
- async def emit(self, event, data=None, room=None, skip_sid=None,
+ async def emit(self, event, data=None, to=None, room=None, skip_sid=None,
namespace=None, callback=None):
"""Emit a custom event to one or more connected clients.
@@ -51,13 +51,13 @@
Note: this method is a coroutine.
"""
- return await self.server.emit(event, data=data, room=room,
+ return await self.server.emit(event, data=data, to=to, room=room,
skip_sid=skip_sid,
namespace=namespace or self.namespace,
callback=callback)
- async def send(self, data, room=None, skip_sid=None, namespace=None,
- callback=None):
+ async def send(self, data, to=None, room=None, skip_sid=None,
+ namespace=None, callback=None):
"""Send a message to one or more connected clients.
The only difference with the :func:`socketio.Server.send` method is
@@ -66,10 +66,23 @@
Note: this method is a coroutine.
"""
- return await self.server.send(data, room=room, skip_sid=skip_sid,
+ return await self.server.send(data, to=to, room=room,
+ skip_sid=skip_sid,
namespace=namespace or self.namespace,
callback=callback)
+ async def call(self, event, data=None, to=None, sid=None, namespace=None,
+ timeout=None):
+ """Emit a custom event to a client and wait for the response.
+
+ The only difference with the :func:`socketio.Server.call` method is
+ that when the ``namespace`` argument is not given the namespace
+ associated with the class is used.
+ """
+ return await self.server.call(event, data=data, to=to, sid=sid,
+ namespace=namespace or self.namespace,
+ timeout=timeout)
+
async def close_room(self, room, namespace=None):
"""Close a room.
@@ -192,6 +205,17 @@
namespace=namespace or self.namespace,
callback=callback)
+ async def call(self, event, data=None, namespace=None, timeout=None):
+ """Emit a custom event to the server and wait for the response.
+
+ The only difference with the :func:`socketio.Client.call` method is
+ that when the ``namespace`` argument is not given the namespace
+ associated with the class is used.
+ """
+ return await self.client.call(event, data=data,
+ namespace=namespace or self.namespace,
+ timeout=timeout)
+
async def disconnect(self):
"""Disconnect a client.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/src/socketio/asyncio_pubsub_manager.py
new/python-socketio-5.5.1/src/socketio/asyncio_pubsub_manager.py
--- old/python-socketio-5.4.1/src/socketio/asyncio_pubsub_manager.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/asyncio_pubsub_manager.py
2022-01-11 13:17:25.000000000 +0100
@@ -148,35 +148,34 @@
async def _thread(self):
while True:
try:
- message = await self._listen()
+ async for message in self._listen(): # pragma: no branch
+ data = None
+ if isinstance(message, dict):
+ data = message
+ else:
+ if isinstance(message, bytes): # pragma: no cover
+ try:
+ data = pickle.loads(message)
+ except:
+ pass
+ if data is None:
+ try:
+ data = json.loads(message)
+ except:
+ pass
+ if data and 'method' in data:
+ self._get_logger().info('pubsub message: {}'.format(
+ data['method']))
+ if data['method'] == 'emit':
+ await self._handle_emit(data)
+ elif data['method'] == 'callback':
+ await self._handle_callback(data)
+ elif data['method'] == 'disconnect':
+ await self._handle_disconnect(data)
+ elif data['method'] == 'close_room':
+ await self._handle_close_room(data)
except asyncio.CancelledError: # pragma: no cover
break
- except:
+ except: # pragma: no cover
import traceback
traceback.print_exc()
- break
- data = None
- if isinstance(message, dict):
- data = message
- else:
- if isinstance(message, bytes): # pragma: no cover
- try:
- data = pickle.loads(message)
- except:
- pass
- if data is None:
- try:
- data = json.loads(message)
- except:
- pass
- if data and 'method' in data:
- self._get_logger().info('pubsub message: {}'.format(
- data['method']))
- if data['method'] == 'emit':
- await self._handle_emit(data)
- elif data['method'] == 'callback':
- await self._handle_callback(data)
- elif data['method'] == 'disconnect':
- await self._handle_disconnect(data)
- elif data['method'] == 'close_room':
- await self._handle_close_room(data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/src/socketio/asyncio_redis_manager.py
new/python-socketio-5.5.1/src/socketio/asyncio_redis_manager.py
--- old/python-socketio-5.4.1/src/socketio/asyncio_redis_manager.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/asyncio_redis_manager.py
2022-01-11 13:17:25.000000000 +0100
@@ -1,6 +1,5 @@
import asyncio
import pickle
-from urllib.parse import urlparse
try:
import aioredis
@@ -10,34 +9,18 @@
from .asyncio_pubsub_manager import AsyncPubSubManager
-def _parse_redis_url(url):
- p = urlparse(url)
- if p.scheme not in {'redis', 'rediss'}:
- raise ValueError('Invalid redis url')
- ssl = p.scheme == 'rediss'
- host = p.hostname or 'localhost'
- port = p.port or 6379
- password = p.password
- if p.path:
- db = int(p.path[1:])
- else:
- db = 0
- return host, port, password, db, ssl
-
-
class AsyncRedisManager(AsyncPubSubManager): # pragma: no cover
"""Redis based client manager for asyncio servers.
This class implements a Redis backend for event sharing across multiple
- processes. Only kept here as one more example of how to build a custom
- backend, since the kombu backend is perfectly adequate to support a Redis
- message queue.
+ processes.
- To use a Redis backend, initialize the :class:`Server` instance as
+ To use a Redis backend, initialize the :class:`AsyncServer` instance as
follows::
- server = socketio.Server(client_manager=socketio.AsyncRedisManager(
- 'redis://hostname:port/0'))
+ url = 'redis://hostname:port/0'
+ server = socketio.AsyncServer(
+ client_manager=socketio.AsyncRedisManager(url))
:param url: The connection URL for the Redis server. For a default Redis
store running on the same host, use ``redis://``. To use an
@@ -47,62 +30,73 @@
:param write_only: If set to ``True``, only initialize to emit events. The
default of ``False`` initializes the class for emitting
and receiving.
+ :param redis_options: additional keyword arguments to be passed to
+ ``aioredis.from_url()``.
"""
name = 'aioredis'
def __init__(self, url='redis://localhost:6379/0', channel='socketio',
- write_only=False, logger=None):
+ write_only=False, logger=None, redis_options=None):
if aioredis is None:
raise RuntimeError('Redis package is not installed '
'(Run "pip install aioredis" in your '
'virtualenv).')
- (
- self.host, self.port, self.password, self.db, self.ssl
- ) = _parse_redis_url(url)
- self.pub = None
- self.sub = None
+ if not hasattr(aioredis.Redis, 'from_url'):
+ raise RuntimeError('Version 2 of aioredis package is required.')
+ self.redis_url = url
+ self.redis_options = redis_options or {}
+ self._redis_connect()
super().__init__(channel=channel, write_only=write_only, logger=logger)
+ def _redis_connect(self):
+ self.redis = aioredis.Redis.from_url(self.redis_url,
+ **self.redis_options)
+ self.pubsub = self.redis.pubsub(ignore_subscribe_messages=True)
+
async def _publish(self, data):
retry = True
while True:
try:
- if self.pub is None:
- self.pub = await aioredis.create_redis(
- (self.host, self.port), db=self.db,
- password=self.password, ssl=self.ssl
- )
- return await self.pub.publish(self.channel,
- pickle.dumps(data))
- except (aioredis.RedisError, OSError):
+ if not retry:
+ self._redis_connect()
+ return await self.redis.publish(
+ self.channel, pickle.dumps(data))
+ except aioredis.exceptions.RedisError:
if retry:
self._get_logger().error('Cannot publish to redis... '
'retrying')
- self.pub = None
retry = False
else:
self._get_logger().error('Cannot publish to redis... '
'giving up')
break
- async def _listen(self):
+ async def _redis_listen_with_retries(self):
retry_sleep = 1
+ connect = False
while True:
try:
- if self.sub is None:
- self.sub = await aioredis.create_redis(
- (self.host, self.port), db=self.db,
- password=self.password, ssl=self.ssl
- )
- self.ch = (await self.sub.subscribe(self.channel))[0]
- retry_sleep = 1
- return await self.ch.get()
- except (aioredis.RedisError, OSError):
+ if connect:
+ self._redis_connect()
+ await self.pubsub.subscribe(self.channel)
+ retry_sleep = 1
+ async for message in self.pubsub.listen():
+ yield message
+ except aioredis.exceptions.RedisError:
self._get_logger().error('Cannot receive from redis... '
'retrying in '
'{} secs'.format(retry_sleep))
- self.sub = None
+ connect = True
await asyncio.sleep(retry_sleep)
retry_sleep *= 2
if retry_sleep > 60:
retry_sleep = 60
+
+ async def _listen(self):
+ channel = self.channel.encode('utf-8')
+ await self.pubsub.subscribe(self.channel)
+ async for message in self._redis_listen_with_retries():
+ if message['channel'] == channel and \
+ message['type'] == 'message' and 'data' in message:
+ yield message['data']
+ await self.pubsub.unsubscribe(self.channel)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/asyncio_server.py
new/python-socketio-5.5.1/src/socketio/asyncio_server.py
--- old/python-socketio-5.4.1/src/socketio/asyncio_server.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/asyncio_server.py 2022-01-11
13:17:25.000000000 +0100
@@ -210,6 +210,12 @@
timeout=60, **kwargs):
"""Emit a custom event to a client and wait for the response.
+ This method issues an emit with a callback and waits for the callback
+ to be invoked before returning. If the callback isn't invoked before
+ the timeout, then a ``TimeoutError`` exception is raised. If the
+ Socket.IO connection drops during the wait, this method still waits
+ until the specified timeout.
+
:param event: The event name. It can be any string. The event names
``'connect'``, ``'message'`` and ``'disconnect'`` are
reserved and should not be used.
@@ -396,8 +402,6 @@
:param kwargs: keyword arguments to pass to the function.
The return value is a ``asyncio.Task`` object.
-
- Note: this method is a coroutine.
"""
return self.eio.start_background_task(target, *args, **kwargs)
@@ -528,7 +532,8 @@
handler = None
if event in self.handlers[namespace]:
handler = self.handlers[namespace][event]
- elif '*' in self.handlers[namespace]:
+ elif event not in self.reserved_events and \
+ '*' in self.handlers[namespace]:
handler = self.handlers[namespace]['*']
args = (event, *args)
if handler:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/client.py
new/python-socketio-5.5.1/src/socketio/client.py
--- old/python-socketio-5.4.1/src/socketio/client.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/client.py 2022-01-11
13:17:25.000000000 +0100
@@ -68,6 +68,11 @@
packets. Custom json modules must have ``dumps`` and ``loads``
functions that are compatible with the standard library
versions.
+ :param handle_sigint: Set to ``True`` to automatically handle disconnection
+ when the process is interrupted, or to ``False`` to
+ leave interrupt handling to the calling application.
+ Interrupt handling can only be enabled when the
+ client instance is created in the main thread.
The Engine.IO configuration supports the following settings:
@@ -87,12 +92,14 @@
fatal errors are logged even when
``engineio_logger`` is ``False``.
"""
+ reserved_events = ['connect', 'connect_error', 'disconnect']
+
def __init__(self, reconnection=True, reconnection_attempts=0,
reconnection_delay=1, reconnection_delay_max=5,
randomization_factor=0.5, logger=False, serializer='default',
- json=None, **kwargs):
+ json=None, handle_sigint=True, **kwargs):
global original_signal_handler
- if original_signal_handler is None and \
+ if handle_sigint and original_signal_handler is None and \
threading.current_thread() == threading.main_thread():
original_signal_handler = signal.signal(signal.SIGINT,
signal_handler)
@@ -101,8 +108,10 @@
self.reconnection_delay = reconnection_delay
self.reconnection_delay_max = reconnection_delay_max
self.randomization_factor = randomization_factor
+ self.handle_sigint = handle_sigint
engineio_options = kwargs
+ engineio_options['handle_sigint'] = handle_sigint
engineio_logger = engineio_options.pop('engineio_logger', None)
if engineio_logger is not None:
engineio_options['logger'] = engineio_logger
@@ -141,8 +150,8 @@
self.socketio_path = None
self.sid = None
- self.connected = False
- self.namespaces = {}
+ self.connected = False #: Indicates if the client is connected or not.
+ self.namespaces = {} #: set of connected namespaces.
self.handlers = {}
self.namespace_handlers = {}
self.callbacks = {}
@@ -423,6 +432,12 @@
def call(self, event, data=None, namespace=None, timeout=60):
"""Emit a custom event to a client and wait for the response.
+ This method issues an emit with a callback and waits for the callback
+ to be invoked before returning. If the callback isn't invoked before
+ the timeout, then a ``TimeoutError`` exception is raised. If the
+ Socket.IO connection drops during the wait, this method still waits
+ until the specified timeout.
+
:param event: The event name. It can be any string. The event names
``'connect'``, ``'message'`` and ``'disconnect'`` are
reserved and should not be used.
@@ -500,9 +515,9 @@
:param args: arguments to pass to the function.
:param kwargs: keyword arguments to pass to the function.
- This function returns an object compatible with the `Thread` class in
- the Python standard library. The `start()` method on this object is
- already called by this function.
+ This function returns an object that represents the background task,
+ on which the ``join()`` methond can be invoked to wait for the task to
+ complete.
"""
return self.eio.start_background_task(target, *args, **kwargs)
@@ -612,7 +627,8 @@
if namespace in self.handlers:
if event in self.handlers[namespace]:
return self.handlers[namespace][event](*args)
- elif '*' in self.handlers[namespace]:
+ elif event not in self.reserved_events and \
+ '*' in self.handlers[namespace]:
return self.handlers[namespace]['*'](event, *args)
# or else, forward the event to a namespace handler if one exists
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/kafka_manager.py
new/python-socketio-5.5.1/src/socketio/kafka_manager.py
--- old/python-socketio-5.4.1/src/socketio/kafka_manager.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/kafka_manager.py 2022-01-11
13:17:25.000000000 +0100
@@ -24,7 +24,9 @@
server = socketio.Server(client_manager=socketio.KafkaManager(url))
:param url: The connection URL for the Kafka server. For a default Kafka
- store running on the same host, use ``kafka://``.
+ store running on the same host, use ``kafka://``. For a highly
+ available deployment of Kafka, pass a list with all the
+ connection URLs available in your cluster.
:param channel: The channel name (topic) on which the server sends and
receives notifications. Must be the same in all the
servers.
@@ -44,10 +46,12 @@
super(KafkaManager, self).__init__(channel=channel,
write_only=write_only)
- self.kafka_url = url[8:] if url != 'kafka://' else 'localhost:9092'
- self.producer = kafka.KafkaProducer(bootstrap_servers=self.kafka_url)
+ urls = [url] if isinstance(url, str) else url
+ self.kafka_urls = [url[8:] if url != 'kafka://' else 'localhost:9092'
+ for url in urls]
+ self.producer = kafka.KafkaProducer(bootstrap_servers=self.kafka_urls)
self.consumer = kafka.KafkaConsumer(self.channel,
- bootstrap_servers=self.kafka_url)
+ bootstrap_servers=self.kafka_urls)
def _publish(self, data):
self.producer.send(self.channel, value=pickle.dumps(data))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/msgpack_packet.py
new/python-socketio-5.5.1/src/socketio/msgpack_packet.py
--- old/python-socketio-5.4.1/src/socketio/msgpack_packet.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/msgpack_packet.py 2022-01-11
13:17:25.000000000 +0100
@@ -3,6 +3,8 @@
class MsgPackPacket(packet.Packet):
+ uses_binary_events = False
+
def encode(self):
"""Encode the packet for transmission."""
return msgpack.dumps(self._to_dict())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/namespace.py
new/python-socketio-5.5.1/src/socketio/namespace.py
--- old/python-socketio-5.4.1/src/socketio/namespace.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/namespace.py 2022-01-11
13:17:25.000000000 +0100
@@ -37,19 +37,20 @@
def _set_server(self, server):
self.server = server
- def emit(self, event, data=None, room=None, skip_sid=None, namespace=None,
- callback=None):
+ def emit(self, event, data=None, to=None, room=None, skip_sid=None,
+ namespace=None, callback=None):
"""Emit a custom event to one or more connected clients.
The only difference with the :func:`socketio.Server.emit` method is
that when the ``namespace`` argument is not given the namespace
associated with the class is used.
"""
- return self.server.emit(event, data=data, room=room, skip_sid=skip_sid,
+ return self.server.emit(event, data=data, to=to, room=room,
+ skip_sid=skip_sid,
namespace=namespace or self.namespace,
callback=callback)
- def send(self, data, room=None, skip_sid=None, namespace=None,
+ def send(self, data, to=None, room=None, skip_sid=None, namespace=None,
callback=None):
"""Send a message to one or more connected clients.
@@ -57,10 +58,22 @@
that when the ``namespace`` argument is not given the namespace
associated with the class is used.
"""
- return self.server.send(data, room=room, skip_sid=skip_sid,
+ return self.server.send(data, to=to, room=room, skip_sid=skip_sid,
namespace=namespace or self.namespace,
callback=callback)
+ def call(self, event, data=None, to=None, sid=None, namespace=None,
+ timeout=None):
+ """Emit a custom event to a client and wait for the response.
+
+ The only difference with the :func:`socketio.Server.call` method is
+ that when the ``namespace`` argument is not given the namespace
+ associated with the class is used.
+ """
+ return self.server.call(event, data=data, to=to, sid=sid,
+ namespace=namespace or self.namespace,
+ timeout=timeout)
+
def enter_room(self, sid, room, namespace=None):
"""Enter a room.
@@ -170,8 +183,7 @@
namespace=namespace or self.namespace,
callback=callback)
- def send(self, data, room=None, skip_sid=None, namespace=None,
- callback=None):
+ def send(self, data, room=None, namespace=None, callback=None):
"""Send a message to the server.
The only difference with the :func:`socketio.Client.send` method is
@@ -181,6 +193,17 @@
return self.client.send(data, namespace=namespace or self.namespace,
callback=callback)
+ def call(self, event, data=None, namespace=None, timeout=None):
+ """Emit a custom event to the server and wait for the response.
+
+ The only difference with the :func:`socketio.Client.call` method is
+ that when the ``namespace`` argument is not given the namespace
+ associated with the class is used.
+ """
+ return self.client.call(event, data=data,
+ namespace=namespace or self.namespace,
+ timeout=timeout)
+
def disconnect(self):
"""Disconnect from the server.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/packet.py
new/python-socketio-5.5.1/src/socketio/packet.py
--- old/python-socketio-5.4.1/src/socketio/packet.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/packet.py 2022-01-11
13:17:25.000000000 +0100
@@ -19,6 +19,7 @@
# id: ASCII encoded, only if id is not None
# data: JSON dump of data payload
+ uses_binary_events = True
json = _json
def __init__(self, packet_type=EVENT, data=None, namespace=None, id=None,
@@ -27,7 +28,9 @@
self.data = data
self.namespace = namespace
self.id = id
- if binary or (binary is None and self._data_is_binary(self.data)):
+ if self.uses_binary_events and \
+ (binary or (binary is None and self._data_is_binary(
+ self.data))):
if self.packet_type == EVENT:
self.packet_type = BINARY_EVENT
elif self.packet_type == ACK:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/redis_manager.py
new/python-socketio-5.5.1/src/socketio/redis_manager.py
--- old/python-socketio-5.4.1/src/socketio/redis_manager.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/redis_manager.py 2022-01-11
13:17:25.000000000 +0100
@@ -27,7 +27,8 @@
server = socketio.Server(client_manager=socketio.RedisManager(url))
:param url: The connection URL for the Redis server. For a default Redis
- store running on the same host, use ``redis://``.
+ store running on the same host, use ``redis://``. To use an
+ SSL connection, use ``rediss://``.
:param channel: The channel name on which the server sends and receives
notifications. Must be the same in all the servers.
:param write_only: If set to ``True``, only initialize to emit events. The
@@ -69,7 +70,7 @@
def _redis_connect(self):
self.redis = redis.Redis.from_url(self.redis_url,
**self.redis_options)
- self.pubsub = self.redis.pubsub()
+ self.pubsub = self.redis.pubsub(ignore_subscribe_messages=True)
def _publish(self, data):
retry = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/src/socketio/server.py
new/python-socketio-5.5.1/src/socketio/server.py
--- old/python-socketio-5.4.1/src/socketio/server.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/src/socketio/server.py 2022-01-11
13:17:25.000000000 +0100
@@ -106,6 +106,8 @@
fatal errors are logged even when
``engineio_logger`` is ``False``.
"""
+ reserved_events = ['connect', 'disconnect']
+
def __init__(self, client_manager=None, logger=False, serializer='default',
json=None, async_handlers=True, always_connect=False,
**kwargs):
@@ -355,6 +357,12 @@
timeout=60, **kwargs):
"""Emit a custom event to a client and wait for the response.
+ This method issues an emit with a callback and waits for the callback
+ to be invoked before returning. If the callback isn't invoked before
+ the timeout, then a ``TimeoutError`` exception is raised. If the
+ Socket.IO connection drops during the wait, this method still waits
+ until the specified timeout.
+
:param event: The event name. It can be any string. The event names
``'connect'``, ``'message'`` and ``'disconnect'`` are
reserved and should not be used.
@@ -599,9 +607,9 @@
:param args: arguments to pass to the function.
:param kwargs: keyword arguments to pass to the function.
- This function returns an object compatible with the `Thread` class in
- the Python standard library. The `start()` method on this object is
- already called by this function.
+ This function returns an object that represents the background task,
+ on which the ``join()`` methond can be invoked to wait for the task to
+ complete.
"""
return self.eio.start_background_task(target, *args, **kwargs)
@@ -735,7 +743,8 @@
if namespace in self.handlers:
if event in self.handlers[namespace]:
return self.handlers[namespace][event](*args)
- elif '*' in self.handlers[namespace]:
+ elif event not in self.reserved_events and \
+ '*' in self.handlers[namespace]:
return self.handlers[namespace]['*'](event, *args)
# or else, forward the event to a namespace handler if one exists
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/tests/asyncio/test_asyncio_client.py
new/python-socketio-5.5.1/tests/asyncio/test_asyncio_client.py
--- old/python-socketio-5.4.1/tests/asyncio/test_asyncio_client.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/asyncio/test_asyncio_client.py
2022-01-11 13:17:25.000000000 +0100
@@ -838,6 +838,7 @@
c.on('*', catchall_handler)
_run(c._trigger_event('foo', '/', 1, '2'))
_run(c._trigger_event('bar', '/', 1, '2', 3))
+ _run(c._trigger_event('connect', '/')) # should not trigger
handler.assert_called_once_with(1, '2')
catchall_handler.assert_called_once_with('bar', 1, '2', 3)
@@ -891,8 +892,6 @@
side_effect=[ValueError, exceptions.ConnectionError, None]
)
_run(c._handle_reconnect())
- print(wait_for.mock.call_count) # logging to debug #572
- print(wait_for.mock.call_args_list)
assert wait_for.mock.call_count == 3
assert [x[0][1] for x in asyncio.wait_for.mock.call_args_list] == [
1.5,
@@ -914,8 +913,6 @@
side_effect=[ValueError, exceptions.ConnectionError, None]
)
_run(c._handle_reconnect())
- print(wait_for.mock.call_count) # logging to debug #572
- print(wait_for.mock.call_args_list)
assert wait_for.mock.call_count == 3
assert [x[0][1] for x in asyncio.wait_for.mock.call_args_list] == [
1.5,
@@ -931,15 +928,12 @@
)
@mock.patch('socketio.client.random.random', side_effect=[1, 0, 0.5])
def test_handle_reconnect_max_attempts(self, random, wait_for):
- c = asyncio_client.AsyncClient(reconnection_attempts=2)
+ c = asyncio_client.AsyncClient(reconnection_attempts=2, logger=True)
c._reconnect_task = 'foo'
c.connect = AsyncMock(
side_effect=[ValueError, exceptions.ConnectionError, None]
)
_run(c._handle_reconnect())
- print(c.reconnection_attempts)
- print(wait_for.mock.call_count) # logging to debug #572
- print(wait_for.mock.call_args_list)
assert wait_for.mock.call_count == 2
assert [x[0][1] for x in asyncio.wait_for.mock.call_args_list] == [
1.5,
@@ -954,14 +948,12 @@
)
@mock.patch('socketio.client.random.random', side_effect=[1, 0, 0.5])
def test_handle_reconnect_aborted(self, random, wait_for):
- c = asyncio_client.AsyncClient()
+ c = asyncio_client.AsyncClient(logger=True)
c._reconnect_task = 'foo'
c.connect = AsyncMock(
side_effect=[ValueError, exceptions.ConnectionError, None]
)
_run(c._handle_reconnect())
- print(wait_for.mock.call_count) # logging to debug #572
- print(wait_for.mock.call_args_list)
assert wait_for.mock.call_count == 2
assert [x[0][1] for x in asyncio.wait_for.mock.call_args_list] == [
1.5,
@@ -1065,7 +1057,7 @@
_run(c._handle_eio_message('9'))
def test_eio_disconnect(self):
- c = asyncio_client.AsyncClient()
+ c = asyncio_client.AsyncClient(reconnection=False)
c.namespaces = {'/': '1'}
c.connected = True
c._trigger_event = AsyncMock()
@@ -1079,7 +1071,7 @@
assert not c.connected
def test_eio_disconnect_namespaces(self):
- c = asyncio_client.AsyncClient()
+ c = asyncio_client.AsyncClient(reconnection=False)
c.namespaces = {'/foo': '1', '/bar': '2'}
c.connected = True
c._trigger_event = AsyncMock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/tests/asyncio/test_asyncio_namespace.py
new/python-socketio-5.5.1/tests/asyncio/test_asyncio_namespace.py
--- old/python-socketio-5.4.1/tests/asyncio/test_asyncio_namespace.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/asyncio/test_asyncio_namespace.py
2022-01-11 13:17:25.000000000 +0100
@@ -93,13 +93,14 @@
ns._set_server(mock_server)
_run(
ns.emit(
- 'ev', data='data', room='room', skip_sid='skip', callback='cb'
+ 'ev', data='data', to='room', skip_sid='skip', callback='cb'
)
)
ns.server.emit.mock.assert_called_with(
'ev',
data='data',
- room='room',
+ to='room',
+ room=None,
skip_sid='skip',
namespace='/foo',
callback='cb',
@@ -117,6 +118,7 @@
ns.server.emit.mock.assert_called_with(
'ev',
data='data',
+ to=None,
room='room',
skip_sid='skip',
namespace='/bar',
@@ -128,10 +130,11 @@
mock_server = mock.MagicMock()
mock_server.send = AsyncMock()
ns._set_server(mock_server)
- _run(ns.send(data='data', room='room', skip_sid='skip', callback='cb'))
+ _run(ns.send(data='data', to='room', skip_sid='skip', callback='cb'))
ns.server.send.mock.assert_called_with(
'data',
- room='room',
+ to='room',
+ room=None,
skip_sid='skip',
namespace='/foo',
callback='cb',
@@ -147,12 +150,38 @@
)
ns.server.send.mock.assert_called_with(
'data',
+ to=None,
room='room',
skip_sid='skip',
namespace='/bar',
callback='cb',
)
+ def test_call(self):
+ ns = asyncio_namespace.AsyncNamespace('/foo')
+ mock_server = mock.MagicMock()
+ mock_server.call = AsyncMock()
+ ns._set_server(mock_server)
+ _run(ns.call('ev', data='data', to='sid'))
+ ns.server.call.mock.assert_called_with(
+ 'ev',
+ data='data',
+ to='sid',
+ sid=None,
+ namespace='/foo',
+ timeout=None,
+ )
+ _run(ns.call('ev', data='data', sid='sid', namespace='/bar',
+ timeout=45))
+ ns.server.call.mock.assert_called_with(
+ 'ev',
+ data='data',
+ to=None,
+ sid='sid',
+ namespace='/bar',
+ timeout=45,
+ )
+
def test_enter_room(self):
ns = asyncio_namespace.AsyncNamespace('/foo')
ns._set_server(mock.MagicMock())
@@ -294,6 +323,20 @@
'data', namespace='/bar', callback='cb'
)
+ def test_call_client(self):
+ ns = asyncio_namespace.AsyncClientNamespace('/foo')
+ mock_client = mock.MagicMock()
+ mock_client.call = AsyncMock()
+ ns._set_client(mock_client)
+ _run(ns.call('ev', data='data'))
+ ns.client.call.mock.assert_called_with(
+ 'ev', data='data', namespace='/foo', timeout=None
+ )
+ _run(ns.call('ev', data='data', namespace='/bar', timeout=45))
+ ns.client.call.mock.assert_called_with(
+ 'ev', data='data', namespace='/bar', timeout=45
+ )
+
def test_disconnect_client(self):
ns = asyncio_namespace.AsyncClientNamespace('/foo')
mock_client = mock.MagicMock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/tests/asyncio/test_asyncio_pubsub_manager.py
new/python-socketio-5.5.1/tests/asyncio/test_asyncio_pubsub_manager.py
--- old/python-socketio-5.4.1/tests/asyncio/test_asyncio_pubsub_manager.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/asyncio/test_asyncio_pubsub_manager.py
2022-01-11 13:17:25.000000000 +0100
@@ -417,7 +417,7 @@
self.pm._handle_disconnect = AsyncMock()
self.pm._handle_close_room = AsyncMock()
- def messages():
+ async def messages():
import pickle
yield {'method': 'emit', 'value': 'foo'}
@@ -428,12 +428,10 @@
yield pickle.dumps({'method': 'close_room', 'value': 'baz'})
yield 'bad json'
yield b'bad pickled'
+ raise asyncio.CancelledError() # force the thread to exit
- self.pm._listen = AsyncMock(side_effect=list(messages()))
- try:
- _run(self.pm._thread())
- except StopIteration:
- pass
+ self.pm._listen = messages
+ _run(self.pm._thread())
self.pm._handle_emit.mock.assert_called_once_with(
{'method': 'emit', 'value': 'foo'}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/tests/asyncio/test_asyncio_redis_manager.py
new/python-socketio-5.5.1/tests/asyncio/test_asyncio_redis_manager.py
--- old/python-socketio-5.4.1/tests/asyncio/test_asyncio_redis_manager.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/asyncio/test_asyncio_redis_manager.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,73 +0,0 @@
-import sys
-import unittest
-
-import pytest
-
-from socketio import asyncio_redis_manager
-
-
[email protected](sys.version_info < (3, 5), 'only for Python 3.5+')
-class TestAsyncRedisManager(unittest.TestCase):
- def test_default_url(self):
- assert asyncio_redis_manager._parse_redis_url('redis://') == (
- 'localhost',
- 6379,
- None,
- 0,
- False,
- )
-
- def test_only_host_url(self):
- assert asyncio_redis_manager._parse_redis_url(
- 'redis://redis.host'
- ) == ('redis.host', 6379, None, 0, False)
-
- def test_no_db_url(self):
- assert asyncio_redis_manager._parse_redis_url(
- 'redis://redis.host:123/1'
- ) == ('redis.host', 123, None, 1, False)
-
- def test_no_port_url(self):
- assert asyncio_redis_manager._parse_redis_url(
- 'redis://redis.host/1'
- ) == ('redis.host', 6379, None, 1, False)
-
- def test_password(self):
- assert asyncio_redis_manager._parse_redis_url(
- 'redis://:[email protected]/1'
- ) == ('redis.host', 6379, 'pw', 1, False)
-
- def test_no_host_url(self):
- assert asyncio_redis_manager._parse_redis_url('redis://:123/1') == (
- 'localhost',
- 123,
- None,
- 1,
- False,
- )
-
- def test_no_host_password_url(self):
- assert asyncio_redis_manager._parse_redis_url(
- 'redis://:pw@:123/1'
- ) == ('localhost', 123, 'pw', 1, False)
-
- def test_bad_port_url(self):
- with pytest.raises(ValueError):
- asyncio_redis_manager._parse_redis_url('redis://localhost:abc/1')
-
- def test_bad_db_url(self):
- with pytest.raises(ValueError):
- asyncio_redis_manager._parse_redis_url('redis://localhost:abc/z')
-
- def test_bad_scheme_url(self):
- with pytest.raises(ValueError):
- asyncio_redis_manager._parse_redis_url('http://redis.host:123/1')
-
- def test_ssl_scheme(self):
- assert asyncio_redis_manager._parse_redis_url('rediss://') == (
- 'localhost',
- 6379,
- None,
- 0,
- True,
- )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/tests/common/test_client.py
new/python-socketio-5.5.1/tests/common/test_client.py
--- old/python-socketio-5.4.1/tests/common/test_client.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/common/test_client.py 2022-01-11
13:17:25.000000000 +0100
@@ -29,6 +29,7 @@
reconnection_delay=5,
reconnection_delay_max=10,
randomization_factor=0.2,
+ handle_sigint=False,
foo='bar',
)
assert not c.reconnection
@@ -36,7 +37,9 @@
assert c.reconnection_delay == 5
assert c.reconnection_delay_max == 10
assert c.randomization_factor == 0.2
- engineio_client_class().assert_called_once_with(foo='bar')
+ assert not c.handle_sigint
+ engineio_client_class().assert_called_once_with(
+ foo='bar', handle_sigint=False)
assert c.connection_url is None
assert c.connection_headers is None
assert c.connection_transports is None
@@ -89,7 +92,8 @@
@mock.patch('socketio.client.Client._engineio_client_class')
def test_engineio_logger(self, engineio_client_class):
client.Client(engineio_logger='foo')
- engineio_client_class().assert_called_once_with(logger='foo')
+ engineio_client_class().assert_called_once_with(
+ handle_sigint=True, logger='foo')
def test_on_event(self):
c = client.Client()
@@ -939,6 +943,7 @@
c.on('*', catchall_handler)
c._trigger_event('foo', '/', 1, '2')
c._trigger_event('bar', '/', 1, '2', 3)
+ c._trigger_event('connect', '/') # should not trigger
handler.assert_called_once_with(1, '2')
catchall_handler.assert_called_once_with('bar', 1, '2', 3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-socketio-5.4.1/tests/common/test_msgpack_packet.py
new/python-socketio-5.5.1/tests/common/test_msgpack_packet.py
--- old/python-socketio-5.4.1/tests/common/test_msgpack_packet.py
2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/common/test_msgpack_packet.py
2022-01-11 13:17:25.000000000 +0100
@@ -22,3 +22,15 @@
assert p.data == p2.data
assert p.id == p2.id
assert p.namespace == p2.namespace
+
+ def test_encode_binary_event_packet(self):
+ p = msgpack_packet.MsgPackPacket(packet.EVENT, data={'foo': b'bar'})
+ assert p.packet_type == packet.EVENT
+ p2 = msgpack_packet.MsgPackPacket(encoded_packet=p.encode())
+ assert p2.data == {'foo': b'bar'}
+
+ def test_encode_binary_ack_packet(self):
+ p = msgpack_packet.MsgPackPacket(packet.ACK, data={'foo': b'bar'})
+ assert p.packet_type == packet.ACK
+ p2 = msgpack_packet.MsgPackPacket(encoded_packet=p.encode())
+ assert p2.data == {'foo': b'bar'}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/tests/common/test_namespace.py
new/python-socketio-5.5.1/tests/common/test_namespace.py
--- old/python-socketio-5.4.1/tests/common/test_namespace.py 2021-10-14
21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tests/common/test_namespace.py 2022-01-11
13:17:25.000000000 +0100
@@ -56,11 +56,12 @@
def test_emit(self):
ns = namespace.Namespace('/foo')
ns._set_server(mock.MagicMock())
- ns.emit('ev', data='data', room='room', skip_sid='skip', callback='cb')
+ ns.emit('ev', data='data', to='room', skip_sid='skip', callback='cb')
ns.server.emit.assert_called_with(
'ev',
data='data',
- room='room',
+ to='room',
+ room=None,
skip_sid='skip',
namespace='/foo',
callback='cb',
@@ -76,6 +77,7 @@
ns.server.emit.assert_called_with(
'ev',
data='data',
+ to=None,
room='room',
skip_sid='skip',
namespace='/bar',
@@ -85,10 +87,11 @@
def test_send(self):
ns = namespace.Namespace('/foo')
ns._set_server(mock.MagicMock())
- ns.send(data='data', room='room', skip_sid='skip', callback='cb')
+ ns.send(data='data', to='room', skip_sid='skip', callback='cb')
ns.server.send.assert_called_with(
'data',
- room='room',
+ to='room',
+ room=None,
skip_sid='skip',
namespace='/foo',
callback='cb',
@@ -102,12 +105,41 @@
)
ns.server.send.assert_called_with(
'data',
+ to=None,
room='room',
skip_sid='skip',
namespace='/bar',
callback='cb',
)
+ def test_call(self):
+ ns = namespace.Namespace('/foo')
+ ns._set_server(mock.MagicMock())
+ ns.call('ev', data='data', to='sid')
+ ns.server.call.assert_called_with(
+ 'ev',
+ data='data',
+ to='sid',
+ sid=None,
+ namespace='/foo',
+ timeout=None,
+ )
+ ns.call(
+ 'ev',
+ data='data',
+ sid='sid',
+ namespace='/bar',
+ timeout=45,
+ )
+ ns.server.call.assert_called_with(
+ 'ev',
+ data='data',
+ to=None,
+ sid='sid',
+ namespace='/bar',
+ timeout=45,
+ )
+
def test_enter_room(self):
ns = namespace.Namespace('/foo')
ns._set_server(mock.MagicMock())
@@ -200,6 +232,17 @@
'data', namespace='/bar', callback='cb'
)
+ def test_call_client(self):
+ ns = namespace.ClientNamespace('/foo')
+ ns._set_client(mock.MagicMock())
+ ns.call('ev', data='data')
+ ns.client.call.assert_called_with(
+ 'ev', data='data', namespace='/foo', timeout=None)
+ ns.call('ev', data='data', namespace='/bar', timeout=45)
+ ns.client.call.assert_called_with(
+ 'ev', data='data', namespace='/bar', timeout=45
+ )
+
def test_disconnect_client(self):
ns = namespace.ClientNamespace('/foo')
ns._set_client(mock.MagicMock())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-socketio-5.4.1/tox.ini
new/python-socketio-5.5.1/tox.ini
--- old/python-socketio-5.4.1/tox.ini 2021-10-14 21:19:50.000000000 +0200
+++ new/python-socketio-5.5.1/tox.ini 2022-01-11 13:17:25.000000000 +0100
@@ -23,7 +23,7 @@
deps=
flake8
commands=
- flake8 --exclude=".*" --ignore=W503,E402,E722 src/socketio tests
+ flake8 --exclude=".*" --ignore=W503,E402,E722 src/socketio tests examples
[testenv:docs]
changedir=docs