Hello community,

here is the log from the commit of package python-stomp.py for openSUSE:Factory 
checked in at 2018-07-18 22:54:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-stomp.py (Old)
 and      /work/SRC/openSUSE:Factory/.python-stomp.py.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-stomp.py"

Wed Jul 18 22:54:26 2018 rev:2 rq:622799 version:4.1.21

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-stomp.py/python-stomp.py.changes  
2018-02-20 17:54:45.799138374 +0100
+++ /work/SRC/openSUSE:Factory/.python-stomp.py.new/python-stomp.py.changes     
2018-07-18 22:55:18.226689531 +0200
@@ -1,0 +2,8 @@
+Sat Jul  7 08:59:00 UTC 2018 - [email protected]
+
+- update to version 4.1.20:
+ * Fix for deadlock issue (https://github.com/jasonrbriggs/stomp.py/issues/197)
+ * Fix for encoding issue (https://github.com/jasonrbriggs/stomp.py/issues/195)
+ * Fix for reconnect issue 
(https://github.com/jasonrbriggs/stomp.py/issues/202)
+
+-------------------------------------------------------------------

Old:
----
  stomp.py-4.1.20.tar.gz

New:
----
  stomp.py-4.1.21.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-stomp.py.spec ++++++
--- /var/tmp/diff_new_pack.WW2FZB/_old  2018-07-18 22:55:19.770684410 +0200
+++ /var/tmp/diff_new_pack.WW2FZB/_new  2018-07-18 22:55:19.774684397 +0200
@@ -13,21 +13,22 @@
 # published by the Open Source Initiative.
 
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
+#
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-stomp.py
-Version:        4.1.20
+Version:        4.1.21
 Release:        0
-License:        Apache-2.0
 Summary:        Python STOMP client
-Url:            https://github.com/jasonrbriggs/stomp.py
+License:        Apache-2.0
 Group:          Development/Languages/Python
+Url:            https://github.com/jasonrbriggs/stomp.py
 Source:         
https://files.pythonhosted.org/packages/source/s/stomp.py/stomp.py-%{version}.tar.gz
-BuildRequires:  python-rpm-macros
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
+BuildRequires:  python-rpm-macros
 Requires:       python-docopt >= 0.6.2
 BuildArch:      noarch
 

++++++ stomp.py-4.1.20.tar.gz -> stomp.py-4.1.21.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/CHANGELOG 
new/stomp.py-4.1.21/CHANGELOG
--- old/stomp.py-4.1.20/CHANGELOG       2018-02-18 10:42:04.000000000 +0100
+++ new/stomp.py-4.1.21/CHANGELOG       2018-07-07 10:12:06.000000000 +0200
@@ -1,4 +1,11 @@
-Version 4.1.20 -
+Version 4.1.21 -
+
+ * Fix for deadlock issue (https://github.com/jasonrbriggs/stomp.py/issues/197)
+ * Fix for encoding issue (https://github.com/jasonrbriggs/stomp.py/issues/195)
+ * Fix for reconnect issue 
(https://github.com/jasonrbriggs/stomp.py/issues/202)
+
+
+Version 4.1.20 - Feb 2018
 
  * Tidy up API (remove need for start/stop methods on the connection)
  * Make updating listeners thread-safe 
(https://github.com/jasonrbriggs/stomp.py/pull/174)
@@ -7,7 +14,7 @@
  * Add missing on_receiver_loop_completed handler to ConnectionListener
 
 
-Version 4.1.19 -
+Version 4.1.19
 
  * Replace custom script with setuptools' entry_point for creating the 
executable
  * Stop waiting for protocol answers when the connection has been closed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/MANIFEST.in 
new/stomp.py-4.1.21/MANIFEST.in
--- old/stomp.py-4.1.20/MANIFEST.in     2017-03-09 23:08:19.000000000 +0100
+++ new/stomp.py-4.1.21/MANIFEST.in     2018-06-29 13:37:36.000000000 +0200
@@ -1,5 +1,6 @@
 include LICENSE
 include CHANGELOG
+include README.rst
 include *.conf
 include *.dox
 include stomp/test/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/PKG-INFO new/stomp.py-4.1.21/PKG-INFO
--- old/stomp.py-4.1.20/PKG-INFO        2018-02-18 10:45:49.000000000 +0100
+++ new/stomp.py-4.1.21/PKG-INFO        2018-07-07 10:14:14.000000000 +0200
@@ -1,12 +1,96 @@
 Metadata-Version: 1.1
 Name: stomp.py
-Version: 4.1.20
+Version: 4.1.21
 Summary: Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of the 
protocol
 Home-page: https://github.com/jasonrbriggs/stomp.py
 Author: Jason R Briggs
 Author-email: [email protected]
 License: Apache
-Description: UNKNOWN
+Description: ========
+        stomp.py
+        ========
+        
+        .. image:: https://badge.fury.io/py/stomp.py.svg
+           :target: https://badge.fury.io/py/stomp.py
+           :alt: PyPI version
+        
+        .. image:: https://travis-ci.org/jasonrbriggs/stomp.py.svg
+           :target: https://travis-ci.org/jasonrbriggs/stomp.py
+           :alt: Build Status
+        
+        "stomp.py" is a Python client library for accessing messaging servers 
(such as ActiveMQ_, Apollo_ or RabbitMQ_) using the STOMP_ protocol (`STOMP 
v1.0`_, `STOMP v1.1`_ and `STOMP v1.2`_). It can also be run as a standalone, 
command-line client for testing.
+        
+        **NOTE:** Stomp.py is officially ending support for Python2.x by Jan 
2020. See `python3statement.org`_ for more information. 
+        
+        .. _STOMP: http://stomp.github.io
+        .. _`STOMP v1.0`: http://stomp.github.io/stomp-specification-1.0.html
+        .. _`STOMP v1.1`: http://stomp.github.io/stomp-specification-1.1.html
+        .. _`STOMP v1.2`: http://stomp.github.io/stomp-specification-1.2.html
+        .. _`python3statement.org`: http://python3statement.org/
+        
+        Quick Start
+        ===========
+        
+        You can connect to a message broker running on the local machine, and 
send a message using the following example.
+        
+        .. code:: python
+        
+          import stomp
+        
+          conn = stomp.Connection()
+          conn.set_listener('', MyListener())
+          conn.start()
+          conn.connect('admin', 'password', wait=True)
+          conn.send(body=' '.join(sys.argv[1:]), destination='/queue/test')
+          conn.disconnect()
+        
+        Various documentation and resources include:
+        
+        - `basic example of using stomp.py`_ with a message listener
+        - `command-line interface description`_
+        - installation instructions and downloads on `PyPi stomp.py page`_
+        - `API documentation`_
+        - current `test coverage report`_
+        - `travis continuous integration`_
+        
+        .. _`basic example of using stomp.py`: 
https://github.com/jasonrbriggs/stomp.py/wiki/Simple-Example
+        .. _`command-line interface description`: 
https://github.com/jasonrbriggs/stomp.py/wiki/Command-Line-Access
+        .. _`PyPi stomp.py page`: https://pypi.org/project/stomp.py/
+        .. _`API documentation`: 
http://jasonrbriggs.github.io/stomp.py/index.html
+        .. _`test coverage report`: 
http://jasonrbriggs.github.io/stomp.py/htmlcov/
+        .. _`travis continuous integration`: 
https://travis-ci.org/jasonrbriggs/stomp.py
+        
+        
+        Current version supports:
+        
+        - Python 2.x and 3.x
+        - STOMP version 1.0, 1.1 and 1.2
+        
+        There is also legacy 3.1.7 version using the old 3-series code (see 
`3.1.7 on PyPi`_ and `3.1.7 on GitHub`_).
+        
+        .. _`3.1.7 on PyPi`: https://pypi.org/project/stomp.py/3.1.7/
+        .. _`3.1.7 on GitHub`: 
https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series
+        
+        stomp.py has been perfunctorily tested on:
+        
+        - ActiveMQ_
+        - Apollo_
+        - RabbitMQ_
+        - stompserver_
+        
+        
+        .. _ActiveMQ: http://activemq.apache.org/
+        .. _Apollo: http://activemq.apache.org/apollo/
+        .. _RabbitMQ: http://www.rabbitmq.com
+        .. _stompserver: http://stompserver.rubyforge.org
+        
+        `stomp.py` has been reported to work with JBossMessaging_ in the 
distant past.
+        
+        .. _JBossMessaging: http://www.jboss.org/jbossmessaging
+        
+        For more info on setting up a test server (using virtualbox), contact 
the developer.
+        
+        
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/README.rst 
new/stomp.py-4.1.21/README.rst
--- old/stomp.py-4.1.20/README.rst      1970-01-01 01:00:00.000000000 +0100
+++ new/stomp.py-4.1.21/README.rst      2018-06-29 13:37:36.000000000 +0200
@@ -0,0 +1,84 @@
+========
+stomp.py
+========
+
+.. image:: https://badge.fury.io/py/stomp.py.svg
+   :target: https://badge.fury.io/py/stomp.py
+   :alt: PyPI version
+
+.. image:: https://travis-ci.org/jasonrbriggs/stomp.py.svg
+   :target: https://travis-ci.org/jasonrbriggs/stomp.py
+   :alt: Build Status
+
+"stomp.py" is a Python client library for accessing messaging servers (such as 
ActiveMQ_, Apollo_ or RabbitMQ_) using the STOMP_ protocol (`STOMP v1.0`_, 
`STOMP v1.1`_ and `STOMP v1.2`_). It can also be run as a standalone, 
command-line client for testing.
+
+**NOTE:** Stomp.py is officially ending support for Python2.x by Jan 2020. See 
`python3statement.org`_ for more information. 
+
+.. _STOMP: http://stomp.github.io
+.. _`STOMP v1.0`: http://stomp.github.io/stomp-specification-1.0.html
+.. _`STOMP v1.1`: http://stomp.github.io/stomp-specification-1.1.html
+.. _`STOMP v1.2`: http://stomp.github.io/stomp-specification-1.2.html
+.. _`python3statement.org`: http://python3statement.org/
+
+Quick Start
+===========
+
+You can connect to a message broker running on the local machine, and send a 
message using the following example.
+
+.. code:: python
+
+  import stomp
+
+  conn = stomp.Connection()
+  conn.set_listener('', MyListener())
+  conn.start()
+  conn.connect('admin', 'password', wait=True)
+  conn.send(body=' '.join(sys.argv[1:]), destination='/queue/test')
+  conn.disconnect()
+
+Various documentation and resources include:
+
+- `basic example of using stomp.py`_ with a message listener
+- `command-line interface description`_
+- installation instructions and downloads on `PyPi stomp.py page`_
+- `API documentation`_
+- current `test coverage report`_
+- `travis continuous integration`_
+
+.. _`basic example of using stomp.py`: 
https://github.com/jasonrbriggs/stomp.py/wiki/Simple-Example
+.. _`command-line interface description`: 
https://github.com/jasonrbriggs/stomp.py/wiki/Command-Line-Access
+.. _`PyPi stomp.py page`: https://pypi.org/project/stomp.py/
+.. _`API documentation`: http://jasonrbriggs.github.io/stomp.py/index.html
+.. _`test coverage report`: http://jasonrbriggs.github.io/stomp.py/htmlcov/
+.. _`travis continuous integration`: 
https://travis-ci.org/jasonrbriggs/stomp.py
+
+
+Current version supports:
+
+- Python 2.x and 3.x
+- STOMP version 1.0, 1.1 and 1.2
+
+There is also legacy 3.1.7 version using the old 3-series code (see `3.1.7 on 
PyPi`_ and `3.1.7 on GitHub`_).
+
+.. _`3.1.7 on PyPi`: https://pypi.org/project/stomp.py/3.1.7/
+.. _`3.1.7 on GitHub`: 
https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series
+
+stomp.py has been perfunctorily tested on:
+
+- ActiveMQ_
+- Apollo_
+- RabbitMQ_
+- stompserver_
+
+
+.. _ActiveMQ: http://activemq.apache.org/
+.. _Apollo: http://activemq.apache.org/apollo/
+.. _RabbitMQ: http://www.rabbitmq.com
+.. _stompserver: http://stompserver.rubyforge.org
+
+`stomp.py` has been reported to work with JBossMessaging_ in the distant past.
+
+.. _JBossMessaging: http://www.jboss.org/jbossmessaging
+
+For more info on setting up a test server (using virtualbox), contact the 
developer.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/setup.py new/stomp.py-4.1.21/setup.py
--- old/stomp.py-4.1.20/setup.py        2017-10-16 20:15:06.000000000 +0200
+++ new/stomp.py-4.1.21/setup.py        2018-06-29 13:37:36.000000000 +0200
@@ -3,6 +3,7 @@
 from distutils.core import Command
 from setuptools import setup
 import platform
+import io
 import logging.config
 import os
 import shutil
@@ -18,6 +19,10 @@
 import stomp
 
 
+with io.open('README.rst', 'rt', encoding='utf8') as f:
+    long_description = f.read()
+
+
 class TestCommand(Command):
     user_options = [('test=', 't', 'specific test to run')]
 
@@ -104,6 +109,7 @@
     name='stomp.py',
     version=version(),
     description='Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of 
the protocol',
+    long_description=long_description,
     license='Apache',
     url='https://github.com/jasonrbriggs/stomp.py',
     author='Jason R Briggs',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/__init__.py 
new/stomp.py-4.1.21/stomp/__init__.py
--- old/stomp.py-4.1.20/stomp/__init__.py       2017-10-27 16:12:52.000000000 
+0200
+++ new/stomp.py-4.1.21/stomp/__init__.py       2018-06-29 13:37:36.000000000 
+0200
@@ -12,7 +12,7 @@
 import stomp.connect as connect
 import stomp.listener as listener
 
-__version__ = (4, 1, 20)
+__version__ = (4, 1, 21)
 
 ##
 # Alias for STOMP 1.0 connections.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/adapter/multicast.py 
new/stomp.py-4.1.21/stomp/adapter/multicast.py
--- old/stomp.py-4.1.20/stomp/adapter/multicast.py      2017-08-05 
11:20:45.000000000 +0200
+++ new/stomp.py-4.1.21/stomp/adapter/multicast.py      2018-06-30 
11:50:26.000000000 +0200
@@ -20,9 +20,9 @@
     """
     Transport over multicast connections rather than using a broker.
     """
-    def __init__(self):
+    def __init__(self, encoding):
         Transport.__init__(self, [], False, False, 0.0, 0.0, 0.0, 0.0, 0, 
False, None, None, None, None, False,
-                           DEFAULT_SSL_VERSION, None, None, None)
+                           DEFAULT_SSL_VERSION, None, None, None, encoding)
         self.subscriptions = {}
         self.current_host_and_port = (MCAST_GRP, MCAST_PORT)
 
@@ -81,7 +81,7 @@
             self.notify(frame_type, f.headers, f.body)
         if 'receipt' in f.headers:
             receipt_frame = Frame('RECEIPT', {'receipt-id': 
f.headers['receipt']})
-            lines = convert_frame_to_lines(receipt_frame)
+            lines = convert_frame(receipt_frame)
             self.send(encode(pack(lines)))
         log.debug("Received frame: %r, headers=%r, body=%r", f.cmd, f.headers, 
f.body)
 
@@ -95,11 +95,11 @@
 
 
 class MulticastConnection(BaseConnection, Protocol12):
-    def __init__(self, wait_on_receipt=False):
+    def __init__(self, wait_on_receipt=False, encoding='utf-8'):
         """
         :param bool wait_on_receipt: deprecated, ignored
         """
-        self.transport = MulticastTransport()
+        self.transport = MulticastTransport(encoding)
         self.transport.set_listener('mcast-listener', self)
         self.transactions = {}
         Protocol12.__init__(self, self.transport, (0, 0))
@@ -112,7 +112,7 @@
         :param dict headers:
         :param keyword_headers:
         """
-        pass
+        self.transport.start()
 
     def subscribe(self, destination, id, ack='auto', headers=None, 
**keyword_headers):
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/backward2.py 
new/stomp.py-4.1.21/stomp/backward2.py
--- old/stomp.py-4.1.20/stomp/backward2.py      2017-03-09 23:08:20.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/backward2.py      2018-06-30 11:50:26.000000000 
+0200
@@ -14,7 +14,7 @@
     return raw_input(prompt)
 
 
-def decode(byte_data):
+def decode(byte_data, encoding=''):
     """
     Decode the byte data to a string - in the case of this Py2 version, we 
can't really do anything (Py3 differs).
 
@@ -25,7 +25,7 @@
     return byte_data  # no way to know if it's unicode or not, so just pass 
through unmolested
 
 
-def encode(char_data):
+def encode(char_data, encoding='utf-8'):
     """
     Encode the parameter as a byte string.
 
@@ -34,7 +34,7 @@
     :rtype: bytes
     """
     if type(char_data) is unicode:
-        return char_data.encode('utf-8')
+        return char_data.encode(encoding, 'replace')
     else:
         return char_data
 
@@ -47,7 +47,7 @@
 
     :rtype: bytes
     """
-    return ''.join(encode(p) for p in pieces)
+    return ''.join(pieces)
 
 
 def join(chars=()):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/backward3.py 
new/stomp.py-4.1.21/stomp/backward3.py
--- old/stomp.py-4.1.20/stomp/backward3.py      2017-03-09 23:08:20.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/backward3.py      2018-06-30 11:50:26.000000000 
+0200
@@ -16,7 +16,7 @@
     return input(prompt)
 
 
-def decode(byte_data):
+def decode(byte_data, encoding='utf-8'):
     """
     Decode the byte data to a string if not None.
 
@@ -26,10 +26,10 @@
     """
     if byte_data is None:
         return None
-    return byte_data.decode()
+    return byte_data.decode(encoding, errors='replace')
 
 
-def encode(char_data):
+def encode(char_data, encoding='utf-8'):
     """
     Encode the parameter as a byte string.
 
@@ -38,11 +38,11 @@
     :rtype: bytes
     """
     if type(char_data) is str:
-        return char_data.encode()
+        return char_data.encode(encoding, errors='replace')
     elif type(char_data) is bytes:
         return char_data
     else:
-        raise TypeError('message should be a string or bytes')
+        raise TypeError('message should be a string or bytes, found %s' % 
type(char_data))
 
 
 def pack(pieces=()):
@@ -53,8 +53,7 @@
 
     :rtype: bytes
     """
-    encoded_pieces = (encode(piece) for piece in pieces)
-    return b''.join(encoded_pieces)
+    return b''.join(pieces)
 
 
 def join(chars=()):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/connect.py 
new/stomp.py-4.1.21/stomp/connect.py
--- old/stomp.py-4.1.20/stomp/connect.py        2018-02-17 12:11:53.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/connect.py        2018-06-30 11:50:26.000000000 
+0200
@@ -94,13 +94,14 @@
                  timeout=None,
                  keepalive=None,
                  auto_decode=True,
+                 encoding='utf-8',
                  auto_content_length=True,
                  recv_bytes=1024):
         transport = Transport(host_and_ports, prefer_localhost, 
try_loopback_connect,
                               reconnect_sleep_initial, 
reconnect_sleep_increase, reconnect_sleep_jitter,
                               reconnect_sleep_max, reconnect_attempts_max, 
use_ssl, ssl_key_file, ssl_cert_file,
                               ssl_ca_certs, ssl_cert_validator, 
wait_on_receipt, ssl_version, timeout,
-                              keepalive, None, auto_decode)
+                              keepalive, None, auto_decode, encoding)
         BaseConnection.__init__(self, transport)
         Protocol10.__init__(self, transport, auto_content_length)
 
@@ -146,6 +147,7 @@
                  keepalive=None,
                  vhost=None,
                  auto_decode=True,
+                 encoding='utf-8',
                  auto_content_length=True,
                  heart_beat_receive_scale=1.5,
                  recv_byte=1024):
@@ -153,7 +155,7 @@
                               reconnect_sleep_initial, 
reconnect_sleep_increase, reconnect_sleep_jitter,
                               reconnect_sleep_max, reconnect_attempts_max, 
use_ssl, ssl_key_file, ssl_cert_file,
                               ssl_ca_certs, ssl_cert_validator, 
wait_on_receipt, ssl_version, timeout,
-                              keepalive, vhost, auto_decode)
+                              keepalive, vhost, auto_decode, encoding)
         BaseConnection.__init__(self, transport)
         Protocol11.__init__(self, transport, heartbeats, auto_content_length, 
heart_beat_receive_scale=heart_beat_receive_scale)
 
@@ -199,6 +201,7 @@
                  keepalive=None,
                  vhost=None,
                  auto_decode=True,
+                 encoding='utf-8',
                  auto_content_length=True,
                  heart_beat_receive_scale=1.5,
                  recv_bytes=1024):
@@ -206,7 +209,7 @@
                               reconnect_sleep_initial, 
reconnect_sleep_increase, reconnect_sleep_jitter,
                               reconnect_sleep_max, reconnect_attempts_max, 
use_ssl, ssl_key_file, ssl_cert_file,
                               ssl_ca_certs, ssl_cert_validator, 
wait_on_receipt, ssl_version, timeout,
-                              keepalive, vhost, auto_decode)
+                              keepalive, vhost, auto_decode, encoding)
         BaseConnection.__init__(self, transport)
         Protocol12.__init__(self, transport, heartbeats, auto_content_length, 
heart_beat_receive_scale=heart_beat_receive_scale)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/listener.py 
new/stomp.py-4.1.21/stomp/listener.py
--- old/stomp.py-4.1.20/stomp/listener.py       2018-02-18 10:42:04.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/listener.py       2018-06-30 11:50:26.000000000 
+0200
@@ -416,10 +416,11 @@
         errors, etc)
         """
         return '''Connections: %s
+Disconnects: %s
 Messages sent: %s
 Messages received: %s
 Heartbeats received: %s
-Errors: %s''' % (self.connections, self.messages_sent, self.messages, 
self.heartbeat_count, self.errors)
+Errors: %s''' % (self.connections, self.disconnects, self.messages_sent, 
self.messages, self.heartbeat_count, self.errors)
 
 
 class PrintingListener(ConnectionListener):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/protocol.py 
new/stomp.py-4.1.21/stomp/protocol.py
--- old/stomp.py-4.1.20/stomp/protocol.py       2018-01-12 20:35:20.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/protocol.py       2018-06-30 11:50:26.000000000 
+0200
@@ -3,7 +3,6 @@
 
 import uuid
 
-from stomp.backward import encode
 from stomp.constants import *
 from stomp.exception import ConnectFailedException
 from stomp.listener import *
@@ -162,7 +161,6 @@
         headers[HDR_DESTINATION] = destination
         if content_type:
             headers[HDR_CONTENT_TYPE] = content_type
-        body = encode(body)
         if self.auto_content_length and body and HDR_CONTENT_LENGTH not in 
headers:
             headers[HDR_CONTENT_LENGTH] = len(body)
         self.send_frame(CMD_SEND, headers, body)
@@ -395,7 +393,6 @@
         headers[HDR_DESTINATION] = destination
         if content_type:
             headers[HDR_CONTENT_TYPE] = content_type
-        body = encode(body)
         if self.auto_content_length and body and HDR_CONTENT_LENGTH not in 
headers:
             headers[HDR_CONTENT_LENGTH] = len(body)
         self.send_frame(CMD_SEND, headers, body)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/__init__.py 
new/stomp.py-4.1.21/stomp/test/__init__.py
--- old/stomp.py-4.1.20/stomp/test/__init__.py  2017-06-07 23:27:37.000000000 
+0200
+++ new/stomp.py-4.1.21/stomp/test/__init__.py  2018-06-30 11:50:26.000000000 
+0200
@@ -1,13 +1,11 @@
 import sys
 
-__all__ = ['basic_test', 'ss_test', 'cli_test', 'cli_ssl_test', 's10_test',
+__all__ = ['basic_test', 'nonascii_test', 'ss_test', 'cli_test', 
'cli_ssl_test', 's10_test',
            's11_test', 's12_test', 'rabbitmq_test', 'stompserver_test',
            'misc_test', 'multicast_test', 'ssl_test', 'utils_test',
            'transport_test', 'local_test']
 
 if sys.hexversion >= 0x03000000:
-    __all__.append('p3_nonascii_test')
     __all__.append('p3_backward_test')
 else:
-    __all__.append('p2_nonascii_test')
     __all__.append('p2_backward_test')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/multicast_test.py 
new/stomp.py-4.1.21/stomp/test/multicast_test.py
--- old/stomp.py-4.1.20/stomp/test/multicast_test.py    2017-10-27 
16:12:17.000000000 +0200
+++ new/stomp.py-4.1.21/stomp/test/multicast_test.py    2018-06-30 
11:50:26.000000000 +0200
@@ -82,3 +82,38 @@
         time.sleep(3)
 
         self.assertTrue(self.listener.messages == 1, 'should have only 
received 1 message')
+
+
+class TestNonAsciiViaMulticast(unittest.TestCase):
+    def setUp(self):
+        conn = MulticastConnection(encoding='utf-16')
+        listener = TestListener('123')
+        conn.set_listener('', listener)
+        conn.connect(wait=True)
+        self.conn = conn
+        self.listener = listener
+        self.timestamp = time.strftime('%Y%m%d%H%M%S')
+
+    def tearDown(self):
+        if self.conn:
+            self.conn.disconnect(receipt=None)
+
+    def test_send_nonascii_auto_encoding(self):
+        queuename = '/queue/multicast-nonascii-%s' % self.timestamp
+        self.conn.subscribe(destination=queuename, ack='auto', id='1')
+
+        txt = test_text_for_utf16
+        self.conn.send(body=txt, destination=queuename, receipt='123')
+
+        self.listener.wait_for_message()
+
+        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
+        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
+        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
+
+        (_, msg) = self.listener.get_latest_message()
+
+        if sys.hexversion >= 0x03000000:
+            self.assertEqual(txt, msg)
+        else:
+            self.assertEqual(txt.encode('utf-8'), msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/nonascii_test.py 
new/stomp.py-4.1.21/stomp/test/nonascii_test.py
--- old/stomp.py-4.1.20/stomp/test/nonascii_test.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/stomp.py-4.1.21/stomp/test/nonascii_test.py     2018-06-30 
11:50:26.000000000 +0200
@@ -0,0 +1,161 @@
+# -*- coding: UTF-8 -*-
+
+import filecmp
+import time
+import unittest
+
+import stomp
+from stomp.listener import TestListener
+from stomp.test.testutils import *
+
+
+class TestNonAsciiSend(unittest.TestCase):
+
+    def setUp(self):
+        conn = stomp.Connection(get_default_host(), auto_decode=False)
+        listener = TestListener('123')
+        conn.set_listener('', listener)
+        conn.connect(get_default_user(), get_default_password(), wait=True)
+        self.conn = conn
+        self.listener = listener
+        self.timestamp = time.strftime('%Y%m%d%H%M%S')
+
+    def tearDown(self):
+        if self.conn:
+            self.conn.disconnect(receipt=None)
+
+    def test_send_nonascii(self):
+        queuename = '/queue/nonasciitest-%s' % self.timestamp
+        self.conn.subscribe(destination=queuename, ack='auto', id='1')
+
+        txt = test_text_for_utf8
+        self.conn.send(body=txt, destination=queuename, receipt='123')
+
+        self.listener.wait_for_message()
+
+        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
+        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
+        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
+
+        (_, msg) = self.listener.get_latest_message()
+        self.assertEqual(stomp.backward.encode(txt), msg)
+
+    def test_image_send(self):
+        d = os.path.dirname(os.path.realpath(__file__))
+        srcname = os.path.join(d, 'test.gif')
+        with open(srcname, 'rb') as f:
+            img = f.read()
+
+        queuename = '/queue/nonascii-image-%s' % self.timestamp
+        self.conn.subscribe(destination=queuename, ack='auto', id='1')
+
+        self.conn.send(body=img, destination=queuename, receipt='123')
+
+        self.listener.wait_for_message()
+
+        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
+        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
+        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
+
+        (_, msg) = self.listener.get_latest_message()
+        self.assertEqual(img, msg)
+        destname = os.path.join(d, 'test-out.gif')
+        with open(destname, 'wb') as f:
+            f.write(img)
+
+        self.assertTrue(filecmp.cmp(srcname, destname))
+
+    def test_image_send(self):
+        d = os.path.dirname(os.path.realpath(__file__))
+        srcname = os.path.join(d, 'test.gif.gz')
+        with open(srcname, 'rb') as f:
+            img = f.read()
+
+        queuename = '/queue/nonascii-image-%s' % self.timestamp
+        self.conn.subscribe(destination=queuename, ack='auto', id='1')
+
+        self.conn.send(body=img, destination=queuename, receipt='123')
+
+        self.listener.wait_for_message()
+
+        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
+        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
+        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
+
+        (_, msg) = self.listener.get_latest_message()
+        self.assertEqual(img, msg)
+        destname = os.path.join(d, 'test-out.gif.gz')
+        with open(destname, 'wb') as f:
+            f.write(img)
+
+        self.assertTrue(filecmp.cmp(srcname, destname))
+
+
+class TestNonAsciiSendAutoDecode(unittest.TestCase):
+    def setUp(self):
+        conn = stomp.Connection(get_default_host(), auto_decode=True)
+        listener = TestListener('123')
+        conn.set_listener('', listener)
+        conn.connect(get_default_user(), get_default_password(), wait=True)
+        self.conn = conn
+        self.listener = listener
+        self.timestamp = time.strftime('%Y%m%d%H%M%S')
+
+    def tearDown(self):
+        if self.conn:
+            self.conn.disconnect(receipt=None)
+
+    def test_send_nonascii_auto_decoding(self):
+        queuename = '/queue/nonasciitest2-%s' % self.timestamp
+        self.conn.subscribe(destination=queuename, ack='auto', id='1')
+
+        txt = test_text_for_utf8
+        self.conn.send(body=txt, destination=queuename, receipt='123')
+
+        self.listener.wait_for_message()
+
+        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
+        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
+        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
+
+        (_, msg) = self.listener.get_latest_message()
+
+        if sys.hexversion >= 0x03000000:
+            self.assertEqual(txt, msg)
+        else:
+            self.assertEqual(txt.encode('utf-8'), msg)
+
+
+class TestNonAsciiSendSpecificEncoding(unittest.TestCase):
+    def setUp(self):
+        conn = stomp.Connection(get_default_host(), auto_decode=True, 
encoding='utf-16')
+        listener = TestListener('123')
+        conn.set_listener('', listener)
+        conn.connect(get_default_user(), get_default_password(), wait=True)
+        self.conn = conn
+        self.listener = listener
+        self.timestamp = time.strftime('%Y%m%d%H%M%S')
+
+    def tearDown(self):
+        if self.conn:
+            self.conn.disconnect(receipt=None)
+
+    def test_send_nonascii_auto_encoding(self):
+        queuename = '/queue/nonasciitest2-%s' % self.timestamp
+        self.conn.subscribe(destination=queuename, ack='auto', id='1')
+
+        txt = test_text_for_utf16
+        self.conn.send(body=txt, destination=queuename, receipt='123')
+
+        self.listener.wait_for_message()
+
+        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
+        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
+        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
+
+        (_, msg) = self.listener.get_latest_message()
+
+        if sys.hexversion >= 0x03000000:
+            self.assertEqual(txt, msg)
+        else:
+            self.assertEqual(txt.encode('utf-8'), msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/p2_backward_test.py 
new/stomp.py-4.1.21/stomp/test/p2_backward_test.py
--- old/stomp.py-4.1.20/stomp/test/p2_backward_test.py  2017-03-09 
23:08:20.000000000 +0100
+++ new/stomp.py-4.1.21/stomp/test/p2_backward_test.py  2018-06-30 
11:50:26.000000000 +0200
@@ -4,14 +4,6 @@
 
 
 class TestBackward2(unittest.TestCase):
-    def test_pack_mixed_string_and_bytes(self):
-        lines = ['SEND', '\n', u'header1:test', u'\u6771']
-        self.assertEqual(backward2.encode(backward2.pack(lines)),
-                         'SEND\nheader1:test\xe6\x9d\xb1')
-        lines = ['SEND', '\n', u'header1:test', '\xe6\x9d\xb1']
-        self.assertEqual(backward2.encode(backward2.pack(lines)),
-                         'SEND\nheader1:test\xe6\x9d\xb1')
-
     def test_decode(self):
         self.assertTrue(backward2.decode(None) is None)
         self.assertEqual(b'test', backward2.decode(b'test'))
@@ -19,3 +11,6 @@
     def test_encode(self):
         self.assertEqual(b'test', backward2.encode(u'test'))
         self.assertEqual(b'test', backward2.encode(b'test'))
+
+    def test_pack(self):
+        self.assertEquals(b'testtest', backward2.pack([b'test', b'test']))
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/p2_nonascii_test.py 
new/stomp.py-4.1.21/stomp/test/p2_nonascii_test.py
--- old/stomp.py-4.1.20/stomp/test/p2_nonascii_test.py  2017-10-27 
16:12:17.000000000 +0200
+++ new/stomp.py-4.1.21/stomp/test/p2_nonascii_test.py  1970-01-01 
01:00:00.000000000 +0100
@@ -1,40 +0,0 @@
-# -*- coding: UTF-8 -*-
-
-import time
-import unittest
-
-import stomp
-from stomp.listener import TestListener
-from stomp.test.testutils import *
-
-
-class TestNonAsciiSend(unittest.TestCase):
-
-    def setUp(self):
-        conn = stomp.Connection(get_default_host())
-        listener = TestListener('123')
-        conn.set_listener('', listener)
-        conn.connect(get_default_user(), get_default_password(), wait=True)
-        self.conn = conn
-        self.listener = listener
-        self.timestamp = time.strftime('%Y%m%d%H%M%S')
-
-    def tearDown(self):
-        if self.conn:
-            self.conn.disconnect(receipt=None)
-
-    def test_send_nonascii(self):
-        queuename = '/queue/p2nonasciitest-%s' % self.timestamp
-        self.conn.subscribe(destination=queuename, ack='auto', id="1")
-
-        txt = u'марко'
-        self.conn.send(body=txt, destination=queuename, receipt='123')
-
-        self.listener.wait_for_message()
-
-        self.assertTrue(self.listener.connections == 1, 'should have received 
1 connection acknowledgement')
-        self.assertTrue(self.listener.messages == 1, 'should have received 1 
message')
-        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
-
-        (_, msg) = self.listener.get_latest_message()
-        self.assertEqual(stomp.backward.encode(txt), msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/p2testutils.py 
new/stomp.py-4.1.21/stomp/test/p2testutils.py
--- old/stomp.py-4.1.20/stomp/test/p2testutils.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/stomp.py-4.1.21/stomp/test/p2testutils.py       2018-06-30 
11:50:26.000000000 +0200
@@ -0,0 +1,4 @@
+# -*- coding: utf8 -*-
+
+test_text_for_utf8 = u'марко'
+test_text_for_utf16 = u'ǰ捁楴敶免'
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/p3_backward_test.py 
new/stomp.py-4.1.21/stomp/test/p3_backward_test.py
--- old/stomp.py-4.1.20/stomp/test/p3_backward_test.py  2017-03-09 
23:08:20.000000000 +0100
+++ new/stomp.py-4.1.21/stomp/test/p3_backward_test.py  2018-06-30 
11:50:26.000000000 +0200
@@ -4,14 +4,6 @@
 
 
 class TestBackward3(unittest.TestCase):
-    def test_pack_mixed_string_and_bytes(self):
-        lines = ['SEND', '\n', 'header1:test', '\u6771']
-        self.assertEqual(backward3.encode(backward3.pack(lines)),
-                         b'SEND\nheader1:test\xe6\x9d\xb1')
-        lines = ['SEND', '\n', 'header1:test', b'\xe6\x9d\xb1']
-        self.assertEqual(backward3.encode(backward3.pack(lines)),
-                         b'SEND\nheader1:test\xe6\x9d\xb1')
-
     def test_decode(self):
         self.assertTrue(backward3.decode(None) is None)
         self.assertEqual('test', backward3.decode(b'test'))
@@ -20,3 +12,6 @@
         self.assertEqual(b'test', backward3.encode('test'))
         self.assertEqual(b'test', backward3.encode(b'test'))
         self.assertRaises(TypeError, backward3.encode, None)
+
+    def test_pack(self):
+        self.assertEquals(b'testtest', backward3.pack([b'test', b'test']))
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/p3_nonascii_test.py 
new/stomp.py-4.1.21/stomp/test/p3_nonascii_test.py
--- old/stomp.py-4.1.20/stomp/test/p3_nonascii_test.py  2017-10-27 
16:12:17.000000000 +0200
+++ new/stomp.py-4.1.21/stomp/test/p3_nonascii_test.py  1970-01-01 
01:00:00.000000000 +0100
@@ -1,122 +0,0 @@
-# -*- coding: UTF-8 -*-
-
-import filecmp
-import time
-import unittest
-
-import stomp
-from stomp.listener import TestListener
-from stomp.test.testutils import *
-
-
-class TestNonAsciiSend(unittest.TestCase):
-
-    def setUp(self):
-        conn = stomp.Connection(get_default_host(), auto_decode=False)
-        listener = TestListener('123')
-        conn.set_listener('', listener)
-        conn.connect(get_default_user(), get_default_password(), wait=True)
-        self.conn = conn
-        self.listener = listener
-        self.timestamp = time.strftime('%Y%m%d%H%M%S')
-
-    def tearDown(self):
-        if self.conn:
-            self.conn.disconnect(receipt=None)
-
-    def test_send_nonascii(self):
-        queuename = '/queue/p3nonasciitest-%s' % self.timestamp
-        self.conn.subscribe(destination=queuename, ack='auto', id='1')
-
-        txt = 'марко'
-        self.conn.send(body=txt, destination=queuename, receipt='123')
-
-        self.listener.wait_for_message()
-
-        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
-        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
-        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
-
-        (_, msg) = self.listener.get_latest_message()
-        self.assertEqual(stomp.backward.encode(txt), msg)
-
-    def test_image_send(self):
-        d = os.path.dirname(os.path.realpath(__file__))
-        srcname = os.path.join(d, 'test.gif')
-        with open(srcname, 'rb') as f:
-            img = f.read()
-
-        queuename = '/queue/p3nonascii-image-%s' % self.timestamp
-        self.conn.subscribe(destination=queuename, ack='auto', id='1')
-
-        self.conn.send(body=img, destination=queuename, receipt='123')
-
-        self.listener.wait_for_message()
-
-        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
-        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
-        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
-
-        (_, msg) = self.listener.get_latest_message()
-        self.assertEqual(img, msg)
-        destname = os.path.join(d, 'test-out.gif')
-        with open(destname, 'wb') as f:
-            f.write(img)
-
-        self.assertTrue(filecmp.cmp(srcname, destname))
-
-    def test_image_send(self):
-        d = os.path.dirname(os.path.realpath(__file__))
-        srcname = os.path.join(d, 'test.gif.gz')
-        with open(srcname, 'rb') as f:
-            img = f.read()
-
-        queuename = '/queue/p3nonascii-image-%s' % self.timestamp
-        self.conn.subscribe(destination=queuename, ack='auto', id='1')
-
-        self.conn.send(body=img, destination=queuename, receipt='123')
-
-        self.listener.wait_for_message()
-
-        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
-        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
-        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
-
-        (_, msg) = self.listener.get_latest_message()
-        self.assertEqual(img, msg)
-        destname = os.path.join(d, 'test-out.gif.gz')
-        with open(destname, 'wb') as f:
-            f.write(img)
-
-        self.assertTrue(filecmp.cmp(srcname, destname))
-
-
-class TestNonAsciiSendAutoEncoding(unittest.TestCase):
-    def setUp(self):
-        conn = stomp.Connection(get_default_host(), auto_decode=True)
-        listener = TestListener('123')
-        conn.set_listener('', listener)
-        conn.connect(get_default_user(), get_default_password(), wait=True)
-        self.conn = conn
-        self.listener = listener
-        self.timestamp = time.strftime('%Y%m%d%H%M%S')
-
-    def tearDown(self):
-        if self.conn:
-            self.conn.disconnect(receipt=None)
-
-    def test_send_nonascii_auto_encoding(self):
-        queuename = '/queue/p3nonasciitest2-%s' % self.timestamp
-        self.conn.subscribe(destination=queuename, ack='auto', id='1')
-
-        txt = 'марко'
-        self.conn.send(body=txt, destination=queuename, receipt='123')
-
-        self.listener.wait_for_message()
-
-        self.assertTrue(self.listener.connections >= 1, 'should have received 
1 connection acknowledgement')
-        self.assertTrue(self.listener.messages >= 1, 'should have received 1 
message')
-        self.assertTrue(self.listener.errors == 0, 'should not have received 
any errors')
-
-        (_, msg) = self.listener.get_latest_message()
-        self.assertEqual(txt, msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/p3testutils.py 
new/stomp.py-4.1.21/stomp/test/p3testutils.py
--- old/stomp.py-4.1.20/stomp/test/p3testutils.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/stomp.py-4.1.21/stomp/test/p3testutils.py       2018-06-30 
11:50:26.000000000 +0200
@@ -0,0 +1,4 @@
+# -*- coding: utf8 -*-
+
+test_text_for_utf8 = 'марко'
+test_text_for_utf16 = 'ǰ捁楴敶免'
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/setup.ini 
new/stomp.py-4.1.21/stomp/test/setup.ini
--- old/stomp.py-4.1.20/stomp/test/setup.ini    2017-03-09 23:08:20.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/test/setup.ini    2018-06-30 11:50:26.000000000 
+0200
@@ -1,12 +1,12 @@
 [default]
-host = 10.0.0.113
-port = 62613
+host = 10.0.0.20
+port = 61613
 ssl_port = 62614
 user = admin
 password = password
 
 [ipv6]
-host = fe80::a00:27ff:fe90:3f1a%en1
+host = fe80::a00:27ff:fe90:3f1a%wlp58s0
 port = 62613
 
 [rabbitmq]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/testutils.py 
new/stomp.py-4.1.21/stomp/test/testutils.py
--- old/stomp.py-4.1.20/stomp/test/testutils.py 2017-03-09 23:08:20.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/test/testutils.py 2018-06-30 11:50:26.000000000 
+0200
@@ -19,6 +19,12 @@
 header_re = re.compile(r'[^:]+:.*')
 
 
+if sys.hexversion >= 0x03000000:  # Python 3+
+    from stomp.test.p3testutils import *
+else:  # Python 2
+    from stomp.test.p2testutils import *
+
+
 def get_environ(name):
     try:
         return os.environ[name]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/test/utils_test.py 
new/stomp.py-4.1.21/stomp/test/utils_test.py
--- old/stomp.py-4.1.20/stomp/test/utils_test.py        2017-03-09 
23:08:20.000000000 +0100
+++ new/stomp.py-4.1.21/stomp/test/utils_test.py        2018-06-30 
11:50:26.000000000 +0200
@@ -10,14 +10,14 @@
         self.assertEqual(1, is_localhost(('127.0.0.1', 8000)))
         self.assertEqual(2, is_localhost(('192.168.1.92', 8000)))
 
-    def test_convert_frame_to_lines(self):
+    def test_convert_frame(self):
         f = Frame('SEND', {
             'header1': 'value1',
             'headerNone': None,
             ' no ': ' trimming ',
         }, 'this is the body')
 
-        lines = convert_frame_to_lines(f)
+        lines = convert_frame(f)
 
         s = pack(lines)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/transport.py 
new/stomp.py-4.1.21/stomp/transport.py
--- old/stomp.py-4.1.20/stomp/transport.py      2018-02-17 12:11:53.000000000 
+0100
+++ new/stomp.py-4.1.21/stomp/transport.py      2018-06-30 12:51:09.000000000 
+0200
@@ -55,6 +55,7 @@
     :param bool auto_decode: automatically decode message responses as 
strings, rather than
         leaving them as bytes. This preserves the behaviour as of version 
4.0.16.
         (To be defaulted to False as of the next release)
+    :param encoding: the character encoding to use for the message body
     """
 
     #
@@ -62,7 +63,7 @@
     #
     __content_length_re = 
re.compile(b'^content-length[:]\\s*(?P<value>[0-9]+)', re.MULTILINE)
 
-    def __init__(self, wait_on_receipt=False, auto_decode=True):
+    def __init__(self, wait_on_receipt=False, auto_decode=True, 
encoding='utf-8'):
         self.__recvbuf = b''
         self.listeners = {}
         self.running = False
@@ -84,6 +85,7 @@
         self.__send_wait_condition = threading.Condition()
         self.__connect_wait_condition = threading.Condition()
         self.__auto_decode = auto_decode
+        self.__encoding = encoding
 
     def override_threading(self, create_thread_fc):
         """
@@ -222,30 +224,32 @@
             self.set_connected(False)
 
         with self.__listeners_change_condition:
-            for listener in self.listeners.values():
-                if not listener:
-                    continue
-
-                notify_func = getattr(listener, 'on_%s' % frame_type, None)
-                if not notify_func:
-                    log.debug("listener %s has no method on_%s", listener, 
frame_type)
-                    continue
-                if frame_type in ('heartbeat', 'disconnected'):
-                    notify_func()
-                    continue
-                if frame_type == 'connecting':
-                    notify_func(self.current_host_and_port)
-                    continue
+            listeners = list(self.listeners.values())
 
-                if frame_type == 'error' and not self.connected:
-                    with self.__connect_wait_condition:
-                        self.connection_error = True
-                        self.__connect_wait_condition.notify()
-
-                rtn = notify_func(headers, body)
-                if rtn:
-                    (headers, body) = rtn
-            return (headers, body)
+        for listener in listeners:
+            if not listener:
+                continue
+
+            notify_func = getattr(listener, 'on_%s' % frame_type, None)
+            if not notify_func:
+                log.debug("listener %s has no method on_%s", listener, 
frame_type)
+                continue
+            if frame_type in ('heartbeat', 'disconnected'):
+                notify_func()
+                continue
+            if frame_type == 'connecting':
+                notify_func(self.current_host_and_port)
+                continue
+
+            if frame_type == 'error' and not self.connected:
+                with self.__connect_wait_condition:
+                    self.connection_error = True
+                    self.__connect_wait_condition.notify()
+
+            rtn = notify_func(headers, body)
+            if rtn:
+                (headers, body) = rtn
+        return (headers, body)
 
     def transmit(self, frame):
         """
@@ -254,24 +258,24 @@
         :param Frame frame: the Frame object to transmit
         """
         with self.__listeners_change_condition:
-            for listener in self.listeners.values():
-                if not listener:
-                    continue
-                try:
-                    listener.on_send(frame)
-                except AttributeError:
-                    continue
+            listeners = list(self.listeners.values())
 
-        lines = utils.convert_frame_to_lines(frame)
+        for listener in listeners:
+            if not listener:
+                continue
+            try:
+                listener.on_send(frame)
+            except AttributeError:
+                continue
 
+        lines = utils.convert_frame(frame)
         packed_frame = pack(lines)
 
         if log.isEnabledFor(logging.DEBUG):
             log.debug("Sending frame: %s", lines)
         else:
             log.info("Sending frame: %r, headers=%r", frame.cmd or 
"heartbeat", utils.clean_headers(frame.headers))
-
-        self.send(encode(packed_frame))
+        self.send(packed_frame)
 
     def send(self, encoded_frame):
         """
@@ -327,6 +331,7 @@
         Main loop listening for incoming data.
         """
         log.info("Starting receiver loop")
+        notify_disconnected = True
         try:
             while self.running:
                 try:
@@ -347,7 +352,7 @@
                         #
                         self.__recvbuf = b''
                         self.running = False
-                        self.notify('disconnected')
+                        notify_disconnected = True
                     break
                 finally:
                     self.cleanup()
@@ -357,6 +362,8 @@
                 self.__receiver_thread_exit_condition.notifyAll()
             log.info("Receiver loop ended")
             self.notify('receiver_loop_completed')
+            if notify_disconnected:
+                self.notify('disconnected')
             with self.__connect_wait_condition:
                 self.__connect_wait_condition.notifyAll()
 
@@ -504,9 +511,10 @@
                  keepalive=None,
                  vhost=None,
                  auto_decode=True,
+                 encoding='utf-8',
                  recv_bytes=1024
                  ):
-        BaseTransport.__init__(self, wait_on_receipt, auto_decode)
+        BaseTransport.__init__(self, wait_on_receipt, auto_decode, encoding)
 
         if host_and_ports is None:
             host_and_ports = [('localhost', 61613)]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp/utils.py 
new/stomp.py-4.1.21/stomp/utils.py
--- old/stomp.py-4.1.20/stomp/utils.py  2017-06-07 22:58:21.000000000 +0200
+++ new/stomp.py-4.1.21/stomp/utils.py  2018-06-30 11:50:26.000000000 +0200
@@ -6,7 +6,8 @@
 import socket
 import threading
 
-from stomp.backward import decode, NULL
+from stomp.backward import encode, decode, NULL
+from stomp.constants import *
 
 
 # List of all host names (unqualified, fully-qualified, and IP
@@ -45,6 +46,8 @@
 #
 LINE_END_RE = re.compile('\n|\r\n')
 
+ENC_NEWLINE = encode("\n")
+ENC_NULL = encode(NULL)
 
 def default_create_thread(callback):
     """
@@ -201,7 +204,7 @@
     return x, y
 
 
-def convert_frame_to_lines(frame):
+def convert_frame(frame, body_encoding=None):
     """
     Convert a frame to a list of lines separated by newlines.
 
@@ -210,22 +213,33 @@
     :rtype: list(str)
     """
     lines = []
+
+    body = None
+    if frame.body:
+        if body_encoding:
+            body = encode(frame.body, body_encoding)
+        else:
+            body = encode(frame.body)
+
+        if HDR_CONTENT_LENGTH in frame.headers:
+            frame.headers[HDR_CONTENT_LENGTH] = len(body)
+
     if frame.cmd:
-        lines.append(frame.cmd)
-        lines.append("\n")
+        lines.append(encode(frame.cmd))
+        lines.append(ENC_NEWLINE)
     for key, vals in sorted(frame.headers.items()):
         if vals is None:
             continue
         if type(vals) != tuple:
             vals = (vals,)
         for val in vals:
-            lines.append("%s:%s\n" % (key, val))
-    lines.append("\n")
-    if frame.body:
-        lines.append(frame.body)
+            lines.append(encode("%s:%s\n" % (key, val)))
+    lines.append(ENC_NEWLINE)
+    if body:
+        lines.append(body)
 
     if frame.cmd:
-        lines.append(NULL)
+        lines.append(ENC_NULL)
     return lines
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp.py.egg-info/PKG-INFO 
new/stomp.py-4.1.21/stomp.py.egg-info/PKG-INFO
--- old/stomp.py-4.1.20/stomp.py.egg-info/PKG-INFO      2018-02-18 
10:45:49.000000000 +0100
+++ new/stomp.py-4.1.21/stomp.py.egg-info/PKG-INFO      2018-07-07 
10:14:14.000000000 +0200
@@ -1,12 +1,96 @@
 Metadata-Version: 1.1
 Name: stomp.py
-Version: 4.1.20
+Version: 4.1.21
 Summary: Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of the 
protocol
 Home-page: https://github.com/jasonrbriggs/stomp.py
 Author: Jason R Briggs
 Author-email: [email protected]
 License: Apache
-Description: UNKNOWN
+Description: ========
+        stomp.py
+        ========
+        
+        .. image:: https://badge.fury.io/py/stomp.py.svg
+           :target: https://badge.fury.io/py/stomp.py
+           :alt: PyPI version
+        
+        .. image:: https://travis-ci.org/jasonrbriggs/stomp.py.svg
+           :target: https://travis-ci.org/jasonrbriggs/stomp.py
+           :alt: Build Status
+        
+        "stomp.py" is a Python client library for accessing messaging servers 
(such as ActiveMQ_, Apollo_ or RabbitMQ_) using the STOMP_ protocol (`STOMP 
v1.0`_, `STOMP v1.1`_ and `STOMP v1.2`_). It can also be run as a standalone, 
command-line client for testing.
+        
+        **NOTE:** Stomp.py is officially ending support for Python2.x by Jan 
2020. See `python3statement.org`_ for more information. 
+        
+        .. _STOMP: http://stomp.github.io
+        .. _`STOMP v1.0`: http://stomp.github.io/stomp-specification-1.0.html
+        .. _`STOMP v1.1`: http://stomp.github.io/stomp-specification-1.1.html
+        .. _`STOMP v1.2`: http://stomp.github.io/stomp-specification-1.2.html
+        .. _`python3statement.org`: http://python3statement.org/
+        
+        Quick Start
+        ===========
+        
+        You can connect to a message broker running on the local machine, and 
send a message using the following example.
+        
+        .. code:: python
+        
+          import stomp
+        
+          conn = stomp.Connection()
+          conn.set_listener('', MyListener())
+          conn.start()
+          conn.connect('admin', 'password', wait=True)
+          conn.send(body=' '.join(sys.argv[1:]), destination='/queue/test')
+          conn.disconnect()
+        
+        Various documentation and resources include:
+        
+        - `basic example of using stomp.py`_ with a message listener
+        - `command-line interface description`_
+        - installation instructions and downloads on `PyPi stomp.py page`_
+        - `API documentation`_
+        - current `test coverage report`_
+        - `travis continuous integration`_
+        
+        .. _`basic example of using stomp.py`: 
https://github.com/jasonrbriggs/stomp.py/wiki/Simple-Example
+        .. _`command-line interface description`: 
https://github.com/jasonrbriggs/stomp.py/wiki/Command-Line-Access
+        .. _`PyPi stomp.py page`: https://pypi.org/project/stomp.py/
+        .. _`API documentation`: 
http://jasonrbriggs.github.io/stomp.py/index.html
+        .. _`test coverage report`: 
http://jasonrbriggs.github.io/stomp.py/htmlcov/
+        .. _`travis continuous integration`: 
https://travis-ci.org/jasonrbriggs/stomp.py
+        
+        
+        Current version supports:
+        
+        - Python 2.x and 3.x
+        - STOMP version 1.0, 1.1 and 1.2
+        
+        There is also legacy 3.1.7 version using the old 3-series code (see 
`3.1.7 on PyPi`_ and `3.1.7 on GitHub`_).
+        
+        .. _`3.1.7 on PyPi`: https://pypi.org/project/stomp.py/3.1.7/
+        .. _`3.1.7 on GitHub`: 
https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series
+        
+        stomp.py has been perfunctorily tested on:
+        
+        - ActiveMQ_
+        - Apollo_
+        - RabbitMQ_
+        - stompserver_
+        
+        
+        .. _ActiveMQ: http://activemq.apache.org/
+        .. _Apollo: http://activemq.apache.org/apollo/
+        .. _RabbitMQ: http://www.rabbitmq.com
+        .. _stompserver: http://stompserver.rubyforge.org
+        
+        `stomp.py` has been reported to work with JBossMessaging_ in the 
distant past.
+        
+        .. _JBossMessaging: http://www.jboss.org/jbossmessaging
+        
+        For more info on setting up a test server (using virtualbox), contact 
the developer.
+        
+        
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-4.1.20/stomp.py.egg-info/SOURCES.txt 
new/stomp.py-4.1.21/stomp.py.egg-info/SOURCES.txt
--- old/stomp.py-4.1.20/stomp.py.egg-info/SOURCES.txt   2018-02-18 
10:45:49.000000000 +0100
+++ new/stomp.py-4.1.21/stomp.py.egg-info/SOURCES.txt   2018-07-07 
10:14:14.000000000 +0200
@@ -2,6 +2,7 @@
 LICENSE
 MANIFEST.in
 README
+README.rst
 setup.cfg
 setup.py
 stomp.log.conf
@@ -37,11 +38,12 @@
 stomp/test/local_test.py
 stomp/test/misc_test.py
 stomp/test/multicast_test.py
+stomp/test/nonascii_test.py
 stomp/test/override_threading_test.py
 stomp/test/p2_backward_test.py
-stomp/test/p2_nonascii_test.py
+stomp/test/p2testutils.py
 stomp/test/p3_backward_test.py
-stomp/test/p3_nonascii_test.py
+stomp/test/p3testutils.py
 stomp/test/rabbitmq_test.py
 stomp/test/s10_test.py
 stomp/test/s11_test.py


Reply via email to