Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-stomp.py for openSUSE:Factory 
checked in at 2021-04-19 21:06:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-stomp.py (Old)
 and      /work/SRC/openSUSE:Factory/.python-stomp.py.new.12324 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-stomp.py"

Mon Apr 19 21:06:51 2021 rev:10 rq:886731 version:7.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-stomp.py/python-stomp.py.changes  
2020-07-21 15:50:06.988275349 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-stomp.py.new.12324/python-stomp.py.changes   
    2021-04-19 21:07:29.220163188 +0200
@@ -1,0 +2,26 @@
+Mon Apr 12 15:26:52 UTC 2021 - Sebastian Wagner <sebix+novell....@sebix.at>
+
+- update to version 7.0.0:
+(from v6.1.1):
+ * Add host bind port patch 
(https://github.com/jasonrbriggs/stomp.py/issues/331)
+ * Tidy up based on pycharm suggestions
+ * Change quotes to be consistent (" rather than ')
+(from v6.1.0):
+ * Remove traceback logging (https://github.com/jasonrbriggs/stomp.py/pull/290)
+ * Add support for \r\n EOL handling (as per [stomp protocol 
v1.2](http://stomp.github.io/stomp-specification-1.2.html#Augmented_BNF))
+ * Remove heartbeat loop sleep (issue 
https://github.com/jasonrbriggs/stomp.py/issues/297, 
https://github.com/jasonrbriggs/stomp.py/pull/298)
+ * Update version number using the makefile and the poetry version command
+ * Add `original_headers` access to the Frame so that you can get the original 
value of a header even if a listener modifies it (issue: 
https://github.com/jasonrbriggs/stomp.py/issues/300, PR 
https://github.com/jasonrbriggs/stomp.py/pull/309)
+ * Fix for reconnect failures 
(https://github.com/jasonrbriggs/stomp.py/pull/295)
+ * Fix for double disconnect notifications causing issues with reconnection
+ * Add 'verbose' to stomp.logging (and defaulting the value to False). Log 
lines which dump the stacktrace now use that variable - except for a couple of 
cases (set stomp.logging.verbose = True to change back to the previous 
behaviour)
+
+-------------------------------------------------------------------
+Mon Apr  5 19:10:50 UTC 2021 - Sebastian Wagner <sebix+novell....@sebix.at>
+
+- update to version 6.1.1:
+ * Add host bind port patch 
(https://github.com/jasonrbriggs/stomp.py/issues/331)
+ * Tidy up based on pycharm suggestions
+ * Change quotes to be consistent (" rather than ')
+
+-------------------------------------------------------------------

Old:
----
  python-stomp.py-6.1.0.tar.gz
  stomp.py-6.1.0.tar.gz

New:
----
  python-stomp.py-7.0.0.tar.gz
  stomp.py-7.0.0.tar.gz

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

Other differences:
------------------
++++++ python-stomp.py.spec ++++++
--- /var/tmp/diff_new_pack.RQxD0k/_old  2021-04-19 21:07:29.680163877 +0200
+++ /var/tmp/diff_new_pack.RQxD0k/_new  2021-04-19 21:07:29.684163883 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-stomp.py
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %define skip_python2 1
 Name:           python-stomp.py
-Version:        6.1.0
+Version:        7.0.0
 Release:        0
 Summary:        Python STOMP client
 License:        Apache-2.0
@@ -31,7 +31,7 @@
 BuildRequires:  python-rpm-macros
 Requires:       python-docopt >= 0.6.2
 Requires(post): update-alternatives
-Requires(postun): update-alternatives
+Requires(postun):update-alternatives
 BuildArch:      noarch
 %python_subpackages
 

++++++ python-stomp.py-6.1.0.tar.gz -> python-stomp.py-7.0.0.tar.gz ++++++
++++ 1705 lines of diff (skipped)

++++++ stomp.py-6.1.0.tar.gz -> stomp.py-7.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/PKG-INFO new/stomp.py-7.0.0/PKG-INFO
--- old/stomp.py-6.1.0/PKG-INFO 2020-04-13 13:38:46.096743000 +0200
+++ new/stomp.py-7.0.0/PKG-INFO 2021-04-08 23:32:19.045912700 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: stomp.py
-Version: 6.1.0
+Version: 7.0.0
 Summary: Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of the 
protocol
 Home-page: https://github.com/jasonrbriggs/stomp.py
 License: Apache-2.0
@@ -73,16 +73,23 @@
 
 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`_). This is no longer supported, but (at least as 
of 2018) there were still a couple of reports of this version still being used 
in the wild.
 
+Note: stomp.py now follows `semantic versioning`_:
+
+- MAJOR version for incompatible API changes,
+- MINOR version for functionality added in a backwards compatible manner, and
+- PATCH version for backwards compatible bug fixes.
+
+
 
 Testing
 =======
 
 stomp.py has been perfunctorily tested on:
 
-- Pivotal `RabbitMQ`_   (`rabbitmq_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/rabbitmq_test.py>`_)
-- Apache `ActiveMQ`_   (`activemq_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/activemq_test.py>`_)
-- Apache ActiveMQ `Artemis`_  (`artemis_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/artemis_test.py>`_)
-- `stompserver`_  (`stompserver_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/stompserver_test.py>`_)
+- Pivotal `RabbitMQ`_   (`test_rabbitmq.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_rabbitmq.py>`_)
+- Apache `ActiveMQ`_   (`test_activemq.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_activemq.py>`_)
+- Apache ActiveMQ `Artemis`_  (`test_artemis.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_artemis.py>`_)
+- `stompserver`_  (`test_stompserver.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_stompserver.py>`_)
 
 For testing locally, you'll need to install docker. Once installed:
 
@@ -121,3 +128,5 @@
 
 .. _`buy me a coffee`: https://www.paypal.me/jasonrbriggs
 
+.. _`semantic versioning`: https://semver.org/
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/README.rst 
new/stomp.py-7.0.0/README.rst
--- old/stomp.py-6.1.0/README.rst       2020-02-15 16:24:05.247170200 +0100
+++ new/stomp.py-7.0.0/README.rst       2021-04-01 22:46:33.122966000 +0200
@@ -51,16 +51,23 @@
 
 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`_). This is no longer supported, but (at least as 
of 2018) there were still a couple of reports of this version still being used 
in the wild.
 
+Note: stomp.py now follows `semantic versioning`_:
+
+- MAJOR version for incompatible API changes,
+- MINOR version for functionality added in a backwards compatible manner, and
+- PATCH version for backwards compatible bug fixes.
+
+
 
 Testing
 =======
 
 stomp.py has been perfunctorily tested on:
 
-- Pivotal `RabbitMQ`_   (`rabbitmq_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/rabbitmq_test.py>`_)
-- Apache `ActiveMQ`_   (`activemq_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/activemq_test.py>`_)
-- Apache ActiveMQ `Artemis`_  (`artemis_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/artemis_test.py>`_)
-- `stompserver`_  (`stompserver_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/stompserver_test.py>`_)
+- Pivotal `RabbitMQ`_   (`test_rabbitmq.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_rabbitmq.py>`_)
+- Apache `ActiveMQ`_   (`test_activemq.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_activemq.py>`_)
+- Apache ActiveMQ `Artemis`_  (`test_artemis.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_artemis.py>`_)
+- `stompserver`_  (`test_stompserver.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_stompserver.py>`_)
 
 For testing locally, you'll need to install docker. Once installed:
 
@@ -98,3 +105,5 @@
 .. _`stompserver`: http://stompserver.rubyforge.org
 
 .. _`buy me a coffee`: https://www.paypal.me/jasonrbriggs
+
+.. _`semantic versioning`: https://semver.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/pyproject.toml 
new/stomp.py-7.0.0/pyproject.toml
--- old/stomp.py-6.1.0/pyproject.toml   2020-04-13 13:33:37.759791600 +0200
+++ new/stomp.py-7.0.0/pyproject.toml   2021-04-08 00:15:42.023734300 +0200
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "stomp.py"
-version = "6.1.0"
+version = "7.0.0"
 description = "Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of 
the protocol"
 authors = ["Jason R Briggs <jasonrbri...@gmail.com>"]
 license = "Apache-2.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/setup.py new/stomp.py-7.0.0/setup.py
--- old/stomp.py-6.1.0/setup.py 2020-04-13 13:38:46.095874300 +0200
+++ new/stomp.py-7.0.0/setup.py 2021-04-08 23:32:19.045352700 +0200
@@ -15,9 +15,9 @@
 
 setup_kwargs = {
     'name': 'stomp.py',
-    'version': '6.1.0',
+    'version': '7.0.0',
     'description': 'Python STOMP client, supporting versions 1.0, 1.1 and 1.2 
of the protocol',
-    'long_description': '========\nstomp.py\n========\n\n.. image:: 
https://badge.fury.io/py/stomp.py.svg\n    :target: 
https://badge.fury.io/py/stomp.py\n    :alt: PyPI version\n\n.. image:: 
https://travis-ci.org/jasonrbriggs/stomp.py.svg\n    :target: 
https://travis-ci.org/jasonrbriggs/stomp.py\n    :alt: Build 
Status\n\n"stomp.py" is a Python client library for accessing messaging servers 
(such as ActiveMQ_, Artemis_ 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 has officially ended support 
for Python2.x. See `python3statement.org`_ for more information. \n\n**If you 
find this project useful, why not** `buy me a coffee`_.\n\n.. contents:: \\ \n  
  :depth: 1\n\n\nQuick Start\n===========\n\nYou can connect to a message 
broker running on the local machine, and send a message using the following 
example.\n\n.. code-block:: python\n\n  import stomp\n\n  con
 n = stomp.Connection()\n  conn.connect(\'admin\', \'password\', wait=True)\n  
conn.send(body=\' \'.join(sys.argv[1:]), destination=\'/queue/test\')\n  
conn.disconnect()\n\n\nDocumentation and 
Resources\n===========================\n\n- `Main documentation`_\n- `API 
documentation`_ (see `stomp.github.io`_ for details on the STOMP protocol 
itself)\n- A basic example of using stomp.py with a message listener can be 
found in the `quick start`_ section of the main documentation\n- Description of 
the `command-line interface`_\n- `Travis`_ for continuous integration builds\n- 
Current `test coverage report`_\n- `PyPi stomp.py page`_\n\nThe current version 
of stomp.py supports:\n\n- Python 3.x (Python2 support ended as of Jan 2020)\n- 
STOMP version 1.0, 1.1 and 1.2\n\nThere 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`_). This is no 
longer supported, but (at least as of 2018) there were still a couple of 
reports of this version still bei
 ng used in the wild.\n\n\nTesting\n=======\n\nstomp.py has been perfunctorily 
tested on:\n\n- Pivotal `RabbitMQ`_   (`rabbitmq_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/rabbitmq_test.py>`_)\n-
 Apache `ActiveMQ`_   (`activemq_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/activemq_test.py>`_)\n-
 Apache ActiveMQ `Artemis`_  (`artemis_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/artemis_test.py>`_)\n-
 `stompserver`_  (`stompserver_test.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/stompserver_test.py>`_)\n\nFor
 testing locally, you\'ll need to install docker. Once installed:\n\n#. Create 
the docker image:\n        make docker-image\n#. Run the container:\n        
make run-docker\n#. Run stomp.py unit tests:\n        make test\n#. Cleanup the 
container afterwards if you don\'t need it any more:\n        make 
remove-docker\n\n\n.. _`STOMP`: http://stomp.github.io\n.. _`STOMP v1.0`: 
http://stomp
 .github.io/stomp-specification-1.0.html\n.. _`STOMP v1.1`: 
http://stomp.github.io/stomp-specification-1.1.html\n.. _`STOMP v1.2`: 
http://stomp.github.io/stomp-specification-1.2.html\n.. 
_`python3statement.org`: http://python3statement.org/\n\n.. _`Main 
documentation`: http://jasonrbriggs.github.io/stomp.py/index.html\n.. 
_`stomp.github.io`: http://stomp.github.io/\n.. _`quick start`: 
http://jasonrbriggs.github.io/stomp.py/quickstart.html\n.. _`command-line 
interface`: http://jasonrbriggs.github.io/stomp.py/commandline.html\n.. _`PyPi 
stomp.py page`: https://pypi.org/project/stomp.py/\n.. _`API documentation`: 
http://jasonrbriggs.github.io/stomp.py/api.html\n.. _`test coverage report`: 
http://jasonrbriggs.github.io/stomp.py/htmlcov/\n.. _`Travis`: 
https://travis-ci.org/jasonrbriggs/stomp.py\n\n.. _`3.1.7 on PyPi`: 
https://pypi.org/project/stomp.py/3.1.7/\n.. _`3.1.7 on GitHub`: 
https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series\n\n.. 
_`ActiveMQ`:  http://activemq.apache.or
 g/\n.. _`Artemis`: https://activemq.apache.org/components/artemis/\n.. 
_`RabbitMQ`: http://www.rabbitmq.com\n.. _`stompserver`: 
http://stompserver.rubyforge.org\n\n.. _`buy me a coffee`: 
https://www.paypal.me/jasonrbriggs\n',
+    'long_description': '========\nstomp.py\n========\n\n.. image:: 
https://badge.fury.io/py/stomp.py.svg\n    :target: 
https://badge.fury.io/py/stomp.py\n    :alt: PyPI version\n\n.. image:: 
https://travis-ci.org/jasonrbriggs/stomp.py.svg\n    :target: 
https://travis-ci.org/jasonrbriggs/stomp.py\n    :alt: Build 
Status\n\n"stomp.py" is a Python client library for accessing messaging servers 
(such as ActiveMQ_, Artemis_ 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 has officially ended support 
for Python2.x. See `python3statement.org`_ for more information. \n\n**If you 
find this project useful, why not** `buy me a coffee`_.\n\n.. contents:: \\ \n  
  :depth: 1\n\n\nQuick Start\n===========\n\nYou can connect to a message 
broker running on the local machine, and send a message using the following 
example.\n\n.. code-block:: python\n\n  import stomp\n\n  con
 n = stomp.Connection()\n  conn.connect(\'admin\', \'password\', wait=True)\n  
conn.send(body=\' \'.join(sys.argv[1:]), destination=\'/queue/test\')\n  
conn.disconnect()\n\n\nDocumentation and 
Resources\n===========================\n\n- `Main documentation`_\n- `API 
documentation`_ (see `stomp.github.io`_ for details on the STOMP protocol 
itself)\n- A basic example of using stomp.py with a message listener can be 
found in the `quick start`_ section of the main documentation\n- Description of 
the `command-line interface`_\n- `Travis`_ for continuous integration builds\n- 
Current `test coverage report`_\n- `PyPi stomp.py page`_\n\nThe current version 
of stomp.py supports:\n\n- Python 3.x (Python2 support ended as of Jan 2020)\n- 
STOMP version 1.0, 1.1 and 1.2\n\nThere 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`_). This is no 
longer supported, but (at least as of 2018) there were still a couple of 
reports of this version still bei
 ng used in the wild.\n\nNote: stomp.py now follows `semantic 
versioning`_:\n\n- MAJOR version for incompatible API changes,\n- MINOR version 
for functionality added in a backwards compatible manner, and\n- PATCH version 
for backwards compatible bug fixes.\n\n\n\nTesting\n=======\n\nstomp.py has 
been perfunctorily tested on:\n\n- Pivotal `RabbitMQ`_   (`test_rabbitmq.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_rabbitmq.py>`_)\n-
 Apache `ActiveMQ`_   (`test_activemq.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_activemq.py>`_)\n-
 Apache ActiveMQ `Artemis`_  (`test_artemis.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_artemis.py>`_)\n- 
`stompserver`_  (`test_stompserver.py 
<https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_stompserver.py>`_)\n\nFor
 testing locally, you\'ll need to install docker. Once installed:\n\n#. Create 
the docker image:\n        make docker-image\n#. Run the container:\n        
make run-docker\
 n#. Run stomp.py unit tests:\n        make test\n#. Cleanup the container 
afterwards if you don\'t need it any more:\n        make remove-docker\n\n\n.. 
_`STOMP`: http://stomp.github.io\n.. _`STOMP v1.0`: 
http://stomp.github.io/stomp-specification-1.0.html\n.. _`STOMP v1.1`: 
http://stomp.github.io/stomp-specification-1.1.html\n.. _`STOMP v1.2`: 
http://stomp.github.io/stomp-specification-1.2.html\n.. 
_`python3statement.org`: http://python3statement.org/\n\n.. _`Main 
documentation`: http://jasonrbriggs.github.io/stomp.py/index.html\n.. 
_`stomp.github.io`: http://stomp.github.io/\n.. _`quick start`: 
http://jasonrbriggs.github.io/stomp.py/quickstart.html\n.. _`command-line 
interface`: http://jasonrbriggs.github.io/stomp.py/commandline.html\n.. _`PyPi 
stomp.py page`: https://pypi.org/project/stomp.py/\n.. _`API documentation`: 
http://jasonrbriggs.github.io/stomp.py/api.html\n.. _`test coverage report`: 
http://jasonrbriggs.github.io/stomp.py/htmlcov/\n.. _`Travis`: 
https://travis-ci.org/j
 asonrbriggs/stomp.py\n\n.. _`3.1.7 on PyPi`: 
https://pypi.org/project/stomp.py/3.1.7/\n.. _`3.1.7 on GitHub`: 
https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series\n\n.. 
_`ActiveMQ`:  http://activemq.apache.org/\n.. _`Artemis`: 
https://activemq.apache.org/components/artemis/\n.. _`RabbitMQ`: 
http://www.rabbitmq.com\n.. _`stompserver`: 
http://stompserver.rubyforge.org\n\n.. _`buy me a coffee`: 
https://www.paypal.me/jasonrbriggs\n\n.. _`semantic versioning`: 
https://semver.org/\n',
     'author': 'Jason R Briggs',
     'author_email': 'jasonrbri...@gmail.com',
     'maintainer': None,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/__init__.py 
new/stomp.py-7.0.0/stomp/__init__.py
--- old/stomp.py-6.1.0/stomp/__init__.py        2020-04-13 13:36:24.352790600 
+0200
+++ new/stomp.py-7.0.0/stomp/__init__.py        2021-04-08 23:32:05.949437400 
+0200
@@ -14,7 +14,7 @@
 import stomp.listener as listener
 import stomp.logging as logging
 
-__version__ = (6, 1, 0)
+__version__ = (7, 0, 0)
 
 ##
 # Alias for STOMP 1.0 connections.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/__main__.py 
new/stomp.py-7.0.0/stomp/__main__.py
--- old/stomp.py-6.1.0/stomp/__main__.py        2020-02-15 16:24:05.255170000 
+0100
+++ new/stomp.py-7.0.0/stomp/__main__.py        1980-01-01 01:00:00.000000000 
+0100
@@ -40,9 +40,9 @@
 from docopt import docopt
 
 sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
-from stomp.adapter.multicast import MulticastConnection
 import stomp.colours
 import stomp.utils
+from stomp.adapter.multicast import MulticastConnection
 from stomp.connect import StompConnection10, StompConnection11, 
StompConnection12
 from stomp.listener import ConnectionListener, StatsListener
 
@@ -68,9 +68,10 @@
     A command line interface to the stomp.py client.  See 
:py:class:`stomp.connect.StompConnection11`
     for more information on establishing a connection to a stomp server.
     """
-    def __init__(self, host='localhost', port=61613, user='', passcode='', 
ver='1.1', prompt='> ', verbose=True,
-                 heartbeats=(0, 0), use_ssl=False, ssl_key_file=None, 
ssl_cert_file=None, ssl_ca_file=None, stdin=sys.stdin, stdout=sys.stdout):
-        Cmd.__init__(self, 'Tab', stdin, stdout)
+    def __init__(self, host="localhost", port=61613, user="", passcode="", 
ver="1.1", prompt="> ", verbose=True,
+                 heartbeats=(0, 0), use_ssl=False, ssl_key_file=None, 
ssl_cert_file=None, ssl_ca_file=None,
+                 stdin=sys.stdin, stdout=sys.stdout):
+        Cmd.__init__(self, "Tab", stdin, stdout)
         ConnectionListener.__init__(self)
         self.__start = True
         self.prompt = prompt
@@ -90,7 +91,7 @@
             raise RuntimeError("Unknown version")
         if use_ssl:
             self.conn.set_ssl([(host, port)], key_file=ssl_key_file, 
cert_file=ssl_cert_file, ca_certs=ssl_ca_file)
-        self.conn.set_listener('', self)
+        self.conn.set_listener("", self)
         self.conn.connect(self.user, self.passcode, wait=True)
         self.transaction_id = None
         self.version = ver
@@ -101,7 +102,7 @@
         self.__subscriptions = {}
         self.__subscription_id = 1
 
-    def __print_async(self, frame_type, headers, body):
+    def __print_async(self, frame_type, frame):
         """
         Utility function to print a message and setup the command prompt
         for the next input
@@ -110,18 +111,18 @@
             return
         if self.verbose:
             self.__sysout(frame_type)
-            for k, v in headers.items():
+            for k, v in frame.headers.items():
                 self.__sysout("%s: %s" % (k, v))
         else:
-            if "message-id" in headers:
-                self.__sysout("message-id: %s" % headers["message-id"])
-            if "subscription" in headers:
-                self.__sysout("subscription: %s" % headers["subscription"])
-        if self.prompt != '':
-            self.__sysout('')
-        self.__sysout(body)
+            if "message-id" in frame.headers:
+                self.__sysout("message-id: %s" % frame.headers["message-id"])
+            if "subscription" in frame.headers:
+                self.__sysout("subscription: %s" % 
frame.headers["subscription"])
+        if self.prompt != "":
+            self.__sysout("")
+        self.__sysout(frame.body)
         if not self.__start:
-            self.__sysout(self.prompt, end='')
+            self.__sysout(self.prompt, end="")
         else:
             self.__start = False
         self.stdout.flush()
@@ -147,43 +148,42 @@
         if not self.__quit:
             self.__error("lost connection")
 
-    def on_message(self, headers, body):
+    def on_message(self, frame):
         """
         See :py:meth:`ConnectionListener.on_message`
 
         Special case: if the header 'filename' is present, the content is 
written out
         as a file
         """
-        self.__sysout('')
-        if "filename" in headers:
-            content = base64.b64decode(body.encode())
-            if os.path.exists(headers["filename"]):
-                fname = "%s.%s" % (headers["filename"], int(time.time()))
+        self.__sysout("")
+        if "filename" in frame.headers:
+            content = base64.b64decode(frame.body.encode())
+            if os.path.exists(frame.headers["filename"]):
+                fname = "%s.%s" % (frame.headers["filename"], int(time.time()))
             else:
-                fname = headers["filename"]
-            with open(fname, 'wb') as f:
+                fname = frame.headers["filename"]
+            with open(fname, "wb") as f:
                 f.write(content)
-            self.__print_async("MESSAGE", headers, "Saved file: %s" % fname)
-        else:
-            self.__print_async("MESSAGE", headers, body)
+            frame.body = "Saved file: %s" % fname
+        self.__print_async("MESSAGE", frame)
 
-    def on_error(self, headers, body):
+    def on_error(self, frame):
         """
         See :py:meth:`ConnectionListener.on_error`
         """
-        self.__print_async("ERROR", headers, body)
+        self.__print_async("ERROR", frame)
 
-    def on_receipt(self, headers, body):
+    def on_receipt(self, frame):
         """
         See :py:meth:`ConnectionListener.on_receipt`
         """
-        self.__print_async("RECEIPT", headers, body)
+        self.__print_async("RECEIPT", frame)
 
-    def on_connected(self, headers, body):
+    def on_connected(self, frame):
         """
         See :py:meth:`ConnectionListener.on_connected`
         """
-        self.__print_async("CONNECTED", headers, body)
+        self.__print_async("CONNECTED", frame)
 
     def on_send(self, frame):
         if self.verbose:
@@ -211,11 +211,11 @@
             "optional": oparams.rstrip()
         }
 
-        if rparams.rstrip() != '':
+        if rparams.rstrip() != "":
             rparams = '''%(hl)sRequired Parameters:%(nc)s%(required)s\n\n''' % 
m
             m["required"] = rparams
 
-        if oparams.rstrip() != '':
+        if oparams.rstrip() != "":
             oparams = '''%(hl)sOptional Parameters:%(nc)s%(optional)s\n\n''' % 
m
             m["optional"] = oparams
 
@@ -291,12 +291,12 @@
         if len(args) < 2:
             self.__error("Expecting: send <destination> <message>")
         elif not self.transaction_id:
-            self.conn.send(args[0], ' '.join(args[1:]))
+            self.conn.send(args[0], " ".join(args[1:]))
         else:
-            self.conn.send(args[0], ' '.join(args[1:]), 
transaction=self.transaction_id)
+            self.conn.send(args[0], " ".join(args[1:]), 
transaction=self.transaction_id)
 
-    def complete_send(self, text, line, begidx, endidx):
-        mline = line.split(' ')[1]
+    def complete_send(self, text, line):
+        mline = line.split(" ")[1]
         offs = len(mline) - len(text)
         return [s[offs:] for s in self.__subscriptions if s.startswith(mline)]
     complete_unsubscribe = complete_send
@@ -314,9 +314,9 @@
         if len(args) < 2:
             self.__error("Expecting: sendrec <destination> <message>")
         elif not self.transaction_id:
-            self.conn.send(args[0], ' '.join(args[1:]), receipt=receipt_id)
+            self.conn.send(args[0], " ".join(args[1:]), receipt=receipt_id)
         else:
-            self.conn.send(args[0], ' '.join(args[1:]), 
transaction=self.transaction_id, receipt=receipt_id)
+            self.conn.send(args[0], " ".join(args[1:]), 
transaction=self.transaction_id, receipt=receipt_id)
 
     def help_sendrec(self):
         self.help("sendrec <destination> <message>",
@@ -328,7 +328,7 @@
         if len(args) < 3:
             self.__error("Expecting: sendreply <destination> <correlation-id> 
<message>")
         else:
-            self.conn.send(args[0], "%s\n" % ' '.join(args[2:]), 
headers={"correlation-id": args[1]})
+            self.conn.send(args[0], "%s\n" % " ".join(args[2:]), 
headers={"correlation-id": args[1]})
 
     def help_sendreply(self):
         self.help("sendreply <destination> <correlation-id> <message>",
@@ -350,11 +350,11 @@
                     self.__error("File %s does not exist" % args[2])
                     return
                 self.__sysout("Loading %s" % args[2])
-                with open(args[2], mode='rb') as jf:
+                with open(args[2], mode="rb") as jf:
                     headers = json.load(jf)
                     self.__sysout("Using headers %s" % str(headers))
 
-            with open(args[1], mode='rb') as f:
+            with open(args[1], mode="rb") as f:
                 s = f.read()
             msg = base64.b64encode(s).decode()
             if not self.transaction_id:
@@ -379,13 +379,13 @@
 
     def check_ack_nack(self, acknackfunc, args):
         if self.nversion >= 1.2 and len(args) < 1:
-            self.__error("Expecting: %s <ack-id>" % cmd)
+            self.__error("Expecting: %s <ack-id>" % acknackfunc)
             return None
         elif self.nversion == 1.1 and len(args) < 2:
-            self.__error("Expecting: %s <message-id> <subscription-id>" % cmd)
+            self.__error("Expecting: %s <message-id> <subscription-id>" % 
acknackfunc)
             return None
         elif len(args) < 1:
-            self.__error("Expecting: %s <message-id>" % cmd)
+            self.__error("Expecting: %s <message-id>" % acknackfunc)
             return None
 
         if self.nversion == 1.1:
@@ -507,9 +507,9 @@
     arguments = docopt(__doc__, version=version_string)
 
     if arguments["--listen"] is not None:
-        prompt = ''
+        prompt = ""
     else:
-        prompt = '> '
+        prompt = "> "
 
     if not heartbeat_pattern.match(arguments["--heartbeats"]):
         print("Invalid heartbeats, expecting cx,cy")
@@ -518,11 +518,11 @@
     heartbeats = tuple(map(int, arguments["--heartbeats"].split(",")))
 
     st = StompCLI(arguments["--host"], arguments["--port"], 
arguments["--user"], arguments["--password"], arguments["--protocol"],
-        prompt, arguments["--verbose"], heartbeats=heartbeats,
-        use_ssl=arguments["--ssl"],
-        ssl_key_file=arguments["--ssl-key-file"],
-        ssl_cert_file=arguments["--ssl-cert-file"],
-        ssl_ca_file=arguments["--ssl-ca-file"])
+                  prompt, arguments["--verbose"], heartbeats=heartbeats,
+                  use_ssl=arguments["--ssl"],
+                  ssl_key_file=arguments["--ssl-key-file"],
+                  ssl_cert_file=arguments["--ssl-cert-file"],
+                  ssl_ca_file=arguments["--ssl-ca-file"])
 
     if arguments["--listen"] is not None:
         st.do_subscribe(arguments["--listen"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/adapter/multicast.py 
new/stomp.py-7.0.0/stomp/adapter/multicast.py
--- old/stomp.py-6.1.0/stomp/adapter/multicast.py       2020-02-15 
16:24:05.255170000 +0100
+++ new/stomp.py-7.0.0/stomp/adapter/multicast.py       1980-01-01 
01:00:00.000000000 +0100
@@ -35,7 +35,7 @@
         self.receiver_socket = socket.socket(socket.AF_INET, 
socket.SOCK_DGRAM, socket.IPPROTO_UDP)
         self.receiver_socket.setsockopt(socket.SOL_SOCKET, 
socket.SO_REUSEADDR, 1)
         self.receiver_socket.setsockopt(socket.SOL_SOCKET, 
socket.SO_REUSEPORT, 1)
-        self.receiver_socket.bind(('', MCAST_PORT))
+        self.receiver_socket.bind(("", MCAST_PORT))
         mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), 
socket.INADDR_ANY)
         self.receiver_socket.setsockopt(socket.IPPROTO_IP, 
socket.IP_ADD_MEMBERSHIP, mreq)
 
@@ -76,8 +76,8 @@
             if frame_type == "message":
                 if f.headers["destination"] not in self.subscriptions.values():
                     return
-                (f.headers, f.body) = self.notify("before_message", f.headers, 
f.body)
-            self.notify(frame_type, f.headers, f.body)
+                self.notify("before_message", f)
+            self.notify(frame_type, f)
         if "receipt" in f.headers:
             receipt_frame = Frame("RECEIPT", {"receipt-id": 
f.headers["receipt"]})
             lines = convert_frame(receipt_frame)
@@ -140,7 +140,7 @@
         Protocol12.disconnect(self, receipt, headers, **keyword_headers)
         self.transport.stop()
 
-    def send_frame(self, cmd, headers=None, body=''):
+    def send_frame(self, cmd, headers=None, body=""):
         """
         :param str cmd:
         :param dict headers:
@@ -148,18 +148,18 @@
         """
         if headers is None:
             headers = {}
-        frame = utils.Frame(cmd, headers, body)
+        frame = Frame(cmd, headers, body)
 
         if cmd == CMD_BEGIN:
             trans = headers[HDR_TRANSACTION]
             if trans in self.transactions:
-                self.notify("error", {}, "Transaction %s already started" % 
trans)
+                self.notify("error", Frame(None, {}, "Transaction %s already 
started" % trans))
             else:
                 self.transactions[trans] = []
         elif cmd == CMD_COMMIT:
             trans = headers[HDR_TRANSACTION]
             if trans not in self.transactions:
-                self.notify("error", {}, "Transaction %s not started" % trans)
+                self.notify("error", Frame(None, {}, "Transaction %s not 
started" % trans))
             else:
                 for f in self.transactions[trans]:
                     self.transport.transmit(f)
@@ -171,7 +171,7 @@
             if "transaction" in headers:
                 trans = headers["transaction"]
                 if trans not in self.transactions:
-                    self.transport.notify("error", {}, "Transaction %s not 
started" % trans)
+                    self.transport.notify("error", Frame(None, {}, 
"Transaction %s not started" % trans))
                     return
                 else:
                     self.transactions[trans].append(frame)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/connect.py 
new/stomp.py-7.0.0/stomp/connect.py
--- old/stomp.py-6.1.0/stomp/connect.py 2020-04-13 13:32:44.543436500 +0200
+++ new/stomp.py-7.0.0/stomp/connect.py 1980-01-01 01:00:00.000000000 +0100
@@ -27,17 +27,19 @@
         self.set_listener("ZZZZZ-disconnect-listener", 
self.disconnect_listener)
         return self
 
+    def disconnect(self, receipt=None, headers=None, **keyword_headers): pass
+
     def __exit__(self, exc_type, exc_val, exc_tb):
         self.disconnect(self.disconnect_receipt_id)
         self.disconnect_listener.wait_on_receipt()
         self.disconnect_listener.wait_on_disconnected()
 
-    def set_listener(self, name, lstnr):
+    def set_listener(self, name, listener):
         """
         :param str name:
-        :param ConnectionListener lstnr:
+        :param ConnectionListener listener:
         """
-        self.transport.set_listener(name, lstnr)
+        self.transport.set_listener(name, listener)
 
     def remove_listener(self, name):
         """
@@ -94,12 +96,12 @@
                  auto_decode=True,
                  encoding="utf-8",
                  auto_content_length=True,
-                 recv_bytes=1024):
+                 bind_host_port=None):
         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, ssl_version, 
timeout,
-                              keepalive, None, auto_decode, encoding)
+                              keepalive, None, auto_decode, encoding, 
bind_host_port=bind_host_port)
         BaseConnection.__init__(self, transport)
         Protocol10.__init__(self, transport, auto_content_length)
 
@@ -148,14 +150,15 @@
                  encoding="utf-8",
                  auto_content_length=True,
                  heart_beat_receive_scale=1.5,
-                 recv_byte=1024):
+                 bind_host_port=None):
         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, ssl_version, 
timeout,
-                              keepalive, vhost, auto_decode, encoding)
+                              keepalive, vhost, auto_decode, encoding, 
bind_host_port=bind_host_port)
         BaseConnection.__init__(self, transport)
-        Protocol11.__init__(self, transport, heartbeats, auto_content_length, 
heart_beat_receive_scale=heart_beat_receive_scale)
+        Protocol11.__init__(self, transport, heartbeats, auto_content_length,
+                            heart_beat_receive_scale=heart_beat_receive_scale)
 
     def connect(self, *args, **kwargs):
         self.transport.start()
@@ -202,14 +205,15 @@
                  encoding="utf-8",
                  auto_content_length=True,
                  heart_beat_receive_scale=1.5,
-                 recv_bytes=1024):
+                 bind_host_port=None):
         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, ssl_version, 
timeout,
-                              keepalive, vhost, auto_decode, encoding, 
is_eol_fc=self.is_eol)
+                              keepalive, vhost, auto_decode, encoding, 
bind_host_port=bind_host_port)
         BaseConnection.__init__(self, transport)
-        Protocol12.__init__(self, transport, heartbeats, auto_content_length, 
heart_beat_receive_scale=heart_beat_receive_scale)
+        Protocol12.__init__(self, transport, heartbeats, auto_content_length,
+                            heart_beat_receive_scale=heart_beat_receive_scale)
 
     def connect(self, *args, **kwargs):
         self.transport.start()
@@ -227,5 +231,6 @@
         if receipt is not None:
             self.transport.stop()
 
-    def is_eol(self, c):
-        return c == b'\x0a' or c == b'\x0d\x0a'
\ No newline at end of file
+    @staticmethod
+    def is_eol(c):
+        return c == b"\x0a" or c == b"\x0d\x0a"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/exception.py 
new/stomp.py-7.0.0/stomp/exception.py
--- old/stomp.py-6.1.0/stomp/exception.py       2020-01-11 22:51:04.332160000 
+0100
+++ new/stomp.py-7.0.0/stomp/exception.py       1980-01-01 01:00:00.000000000 
+0100
@@ -1,6 +1,7 @@
 """Errors thrown by stomp.py connections.
 """
 
+
 class StompException(Exception):
     """
     Common exception class. All specific stomp.py exceptions are subclasses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/listener.py 
new/stomp.py-7.0.0/stomp/listener.py
--- old/stomp.py-6.1.0/stomp/listener.py        2020-04-08 20:52:36.609415300 
+0200
+++ new/stomp.py-7.0.0/stomp/listener.py        1980-01-01 01:00:00.000000000 
+0100
@@ -1,7 +1,6 @@
 """Various listeners for using with stomp.py connections.
 """
 
-import os
 import sys
 import threading
 import time
@@ -51,6 +50,7 @@
     This class should be used as a base class for objects registered
     using Connection.set_listener().
     """
+
     def on_connecting(self, host_and_port):
         """
         Called by the STOMP connection once a TCP/IP connection to the
@@ -64,14 +64,19 @@
         """
         pass
 
-    def on_connected(self, headers, body):
+    def on_connected(self, frame):
         """
         Called by the STOMP connection when a CONNECTED frame is
         received (after a connection has been established or
         re-established).
 
-        :param dict headers: a dictionary containing all headers sent by the 
server as key/value pairs.
-        :param body: the frame's payload. This is usually empty for CONNECTED 
frames.
+        :param Frame frame: the stomp frame
+        """
+        pass
+
+    def on_disconnecting(self):
+        """
+        Called before a DISCONNECT frame is sent.
         """
         pass
 
@@ -90,42 +95,38 @@
         """
         pass
 
-    def on_before_message(self, headers, body):
+    def on_before_message(self, frame):
         """
         Called by the STOMP connection before a message is returned to the 
client app. Returns a tuple
         containing the headers and body (so that implementing listeners can 
pre-process the content).
 
-        :param dict headers: the message headers
-        :param body: the message body
+        :param Frame frame: the stomp frame
         """
-        return headers, body
+        pass
 
-    def on_message(self, headers, body):
+    def on_message(self, frame):
         """
         Called by the STOMP connection when a MESSAGE frame is received.
 
-        :param dict headers: a dictionary containing all headers sent by the 
server as key/value pairs.
-        :param body: the frame's payload - the message body.
+        :param Frame frame: the stomp frame
         """
         pass
 
-    def on_receipt(self, headers, body):
+    def on_receipt(self, frame):
         """
         Called by the STOMP connection when a RECEIPT frame is
         received, sent by the server if requested by the client using
         the 'receipt' header.
 
-        :param dict headers: a dictionary containing all headers sent by the 
server as key/value pairs.
-        :param body: the frame's payload. This is usually empty for RECEIPT 
frames.
+        :param Frame frame: the stomp frame
         """
         pass
 
-    def on_error(self, headers, body):
+    def on_error(self, frame):
         """
         Called by the STOMP connection when an ERROR frame is received.
 
-        :param dict headers: a dictionary containing all headers sent by the 
server as key/value pairs.
-        :param body: the frame's payload - usually a detailed error 
description.
+        :param Frame frame: the stomp frame
         """
         pass
 
@@ -133,7 +134,7 @@
         """
         Called by the STOMP connection when it is in the process of sending a 
message
 
-        :param Frame frame: the frame to be sent
+        :param Frame frame: the stomp frame
         """
         pass
 
@@ -143,7 +144,7 @@
         """
         pass
 
-    def on_receiver_loop_completed(self, headers, body):
+    def on_receiver_loop_completed(self, frame):
         """
         Called when the connection receiver_loop has finished.
         """
@@ -163,19 +164,20 @@
         self.next_outbound_heartbeat = None
         self.heart_beat_receive_scale = heart_beat_receive_scale
         self.heartbeat_terminate_event = threading.Event()
+        self.disconnecting = False
 
-    def on_connected(self, headers, body):
+    def on_connected(self, frame):
         """
         Once the connection is established, and 'heart-beat' is found in the 
headers, we calculate the real
         heartbeat numbers (based on what the server sent and what was 
specified by the client) - if the heartbeats
         are not 0, we start up the heartbeat loop accordingly.
 
-        :param dict headers: headers in the connection message
-        :param body: the message body
+        :param Frame frame: the stomp frame
         """
-        if "heart-beat" in headers:
+        self.disconnecting = False
+        if "heart-beat" in frame.headers:
             self.heartbeats = utils.calculate_heartbeats(
-                headers["heart-beat"].replace(' ', '').split(','), 
self.heartbeats)
+                frame.headers["heart-beat"].replace(" ", "").split(","), 
self.heartbeats)
             logging.debug("Heartbeats calculated %s", str(self.heartbeats))
             if self.heartbeats != (0, 0):
                 self.send_sleep = self.heartbeats[0] / 1000
@@ -200,12 +202,14 @@
         self.running = False
         self.heartbeat_terminate_event.set()
 
-    def on_message(self, headers, body):
+    def on_disconnecting(self):
+        self.disconnecting = True
+
+    def on_message(self, frame):
         """
         Reset the last received time whenever a message is received.
 
-        :param dict headers: headers in the message
-        :param body: the message content
+        :param Frame frame: the stomp frame
         """
         # reset the heartbeat for any received message
         self.__update_heartbeat()
@@ -279,7 +283,7 @@
 
             now = monotonic()
 
-            if not self.transport.is_connected():
+            if not self.transport.is_connected() or self.disconnecting:
                 time.sleep(self.send_sleep)
                 continue
 
@@ -299,7 +303,7 @@
                 if diff_receive > self.receive_sleep:
                     # heartbeat timeout
                     logging.warning("Heartbeat timeout: diff_receive=%s, 
time=%s, lastrec=%s",
-                                diff_receive, now, self.received_heartbeat)
+                                    diff_receive, now, self.received_heartbeat)
                     self.transport.set_connected(False)
                     self.transport.disconnect_socket()
                     self.transport.stop()
@@ -326,14 +330,13 @@
         self.received = False
         self.disconnected = False
 
-    def on_receipt(self, headers, body):
+    def on_receipt(self, frame):
         """
         If the receipt id can be found in the headers, then notify the waiting 
thread.
 
-        :param dict headers: headers in the message
-        :param body: the message content
+        :param Frame frame: the stomp frame
         """
-        if "receipt-id" in headers and headers["receipt-id"] == self.receipt:
+        if "receipt-id" in frame.headers and frame.headers["receipt-id"] == 
self.receipt:
             with self.receipt_condition:
                 self.received = True
                 self.receipt_condition.notify()
@@ -360,6 +363,7 @@
             while not self.disconnected:
                 self.disconnect_condition.wait()
 
+
 class StatsListener(ConnectionListener):
     """
     A connection listener for recording statistics on messages sent and 
received.
@@ -387,17 +391,16 @@
         self.disconnects += 1
         logging.info("disconnected (x %s)", self.disconnects)
 
-    def on_error(self, headers, body):
+    def on_error(self, frame):
         """
         Increment the error count. See :py:meth:`ConnectionListener.on_error`
 
-        :param dict headers: headers in the message
-        :param body: the message content
+        :param Frame frame: the stomp frame
         """
         if logging.isEnabledFor(logging.DEBUG):
-            logging.debug("received an error %s [%s]", body, headers)
+            logging.debug("received an error %s [%s]", frame.body, 
frame.headers)
         else:
-            logging.info("received an error %s", body)
+            logging.info("received an error %s", frame.body)
         self.errors += 1
 
     def on_connecting(self, host_and_port):
@@ -409,12 +412,11 @@
         logging.info("connecting %s %s (x %s)", host_and_port[0], 
host_and_port[1], self.connections)
         self.connections += 1
 
-    def on_message(self, headers, body):
+    def on_message(self, frame):
         """
         Increment the message received count. See 
:py:meth:`ConnectionListener.on_message`
 
-        :param dict headers: headers in the message
-        :param body: the message content
+        :param Frame frame: the stomp frame
         """
         self.messages += 1
 
@@ -449,7 +451,8 @@
 Messages sent: %s
 Messages received: %s
 Heartbeats received: %s
-Errors: %s''' % (self.connections, self.disconnects, 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):
@@ -468,12 +471,11 @@
         """
         self.__print("on_connecting %s %s", *host_and_port)
 
-    def on_connected(self, headers, body):
+    def on_connected(self, frame):
         """
-        :param dict headers:
-        :param body:
+        :param Frame frame: the stomp frame
         """
-        self.__print("on_connected %s %s", headers, body)
+        self.__print("on_connected %s %s", frame.headers, frame.body)
 
     def on_disconnected(self):
         self.__print("on_disconnected")
@@ -481,38 +483,33 @@
     def on_heartbeat_timeout(self):
         self.__print("on_heartbeat_timeout")
 
-    def on_before_message(self, headers, body):
+    def on_before_message(self, frame):
         """
-        :param dict headers:
-        :param body:
+        :param Frame frame: the stomp frame
         """
-        self.__print("on_before_message %s %s", headers, body)
-        return headers, body
+        self.__print("on_before_message %s %s", frame.headers, frame.body)
 
-    def on_message(self, headers, body):
+    def on_message(self, frame):
         """
-        :param dict headers:
-        :param body:
+        :param Frame frame: the stomp frame
         """
-        self.__print("on_message %s %s", headers, body)
+        self.__print("on_message %s %s", frame.headers, frame.body)
 
-    def on_receipt(self, headers, body):
+    def on_receipt(self, frame):
         """
-        :param dict headers:
-        :param body:
+        :param Frame frame: the stomp frame
         """
-        self.__print("on_receipt %s %s", headers, body)
+        self.__print("on_receipt %s %s", frame.headers, frame.body)
 
-    def on_error(self, headers, body):
+    def on_error(self, frame):
         """
-        :param dict headers:
-        :param body:
+        :param Frame frame: the stomp frame
         """
-        self.__print("on_error %s %s", headers, body)
+        self.__print("on_error %s %s", frame.headers, frame.body)
 
     def on_send(self, frame):
         """
-        :param Frame frame:
+        :param Frame frame: the stomp frame
         """
         self.__print("on_send %s %s %s", frame.cmd, 
utils.clean_headers(frame.headers), frame.body)
 
@@ -553,16 +550,15 @@
                 self.heartbeat_condition.wait()
             self.heartbeat_received = False
 
-
     def on_connecting(self, host_and_port):
         StatsListener.on_connecting(self, host_and_port)
         PrintingListener.on_connecting(self, host_and_port)
         WaitingListener.on_connecting(self, host_and_port)
 
-    def on_connected(self, headers, body):
-        StatsListener.on_connected(self, headers, body)
-        PrintingListener.on_connected(self, headers, body)
-        WaitingListener.on_connected(self, headers, body)
+    def on_connected(self, frame):
+        StatsListener.on_connected(self, frame)
+        PrintingListener.on_connected(self, frame)
+        WaitingListener.on_connected(self, frame)
 
     def on_disconnected(self):
         StatsListener.on_disconnected(self)
@@ -574,32 +570,31 @@
         PrintingListener.on_heartbeat_timeout(self)
         WaitingListener.on_heartbeat_timeout(self)
 
-    def on_before_message(self, headers, body):
-        StatsListener.on_before_message(self, headers, body)
-        PrintingListener.on_before_message(self, headers, body)
-        WaitingListener.on_before_message(self, headers, body)
-
-    def on_message(self, headers, message):
-        """
-        :param dict headers:
-        :param message:
-        """
-        StatsListener.on_message(self, headers, message)
-        PrintingListener.on_message(self, headers, message)
-        self.message_list.append((headers, message))
+    def on_before_message(self, frame):
+        StatsListener.on_before_message(self, frame)
+        PrintingListener.on_before_message(self, frame)
+        WaitingListener.on_before_message(self, frame)
+
+    def on_message(self, frame):
+        """
+        :param Frame frame: the stomp frame
+        """
+        StatsListener.on_message(self, frame)
+        PrintingListener.on_message(self, frame)
+        self.message_list.append((frame.headers, frame.body))
         with self.message_condition:
             self.message_received = True
             self.message_condition.notify()
 
-    def on_receipt(self, headers, body):
-        StatsListener.on_receipt(self, headers, body)
-        PrintingListener.on_receipt(self, headers, body)
-        WaitingListener.on_receipt(self, headers, body)
-
-    def on_error(self, headers, body):
-        StatsListener.on_error(self, headers, body)
-        PrintingListener.on_error(self, headers, body)
-        WaitingListener.on_error(self, headers, body)
+    def on_receipt(self, frame):
+        StatsListener.on_receipt(self, frame)
+        PrintingListener.on_receipt(self, frame)
+        WaitingListener.on_receipt(self, frame)
+
+    def on_error(self, frame):
+        StatsListener.on_error(self, frame)
+        PrintingListener.on_error(self, frame)
+        WaitingListener.on_error(self, frame)
 
     def on_send(self, frame):
         StatsListener.on_send(self, frame)
@@ -613,7 +608,7 @@
             self.heartbeat_received = True
             self.heartbeat_condition.notify()
 
-    def on_receiver_loop_completed(self, headers, body):
-        StatsListener.on_receiver_loop_completed(self, headers, body)
-        PrintingListener.on_receiver_loop_completed(self, headers, body)
-        WaitingListener.on_receiver_loop_completed(self, headers, body)
+    def on_receiver_loop_completed(self, frame):
+        StatsListener.on_receiver_loop_completed(self, frame)
+        PrintingListener.on_receiver_loop_completed(self, frame)
+        WaitingListener.on_receiver_loop_completed(self, frame)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/logging.py 
new/stomp.py-7.0.0/stomp/logging.py
--- old/stomp.py-6.1.0/stomp/logging.py 2020-02-15 16:24:05.259170000 +0100
+++ new/stomp.py-7.0.0/stomp/logging.py 1980-01-01 01:00:00.000000000 +0100
@@ -3,6 +3,8 @@
 DEBUG = logging.DEBUG
 INFO = logging.INFO
 
+verbose = False
+
 __logger = logging.getLogger("stomp.py")
 debug = __logger.debug
 info = __logger.info
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/protocol.py 
new/stomp.py-7.0.0/stomp/protocol.py
--- old/stomp.py-6.1.0/stomp/protocol.py        2020-02-20 22:33:18.120868400 
+0100
+++ new/stomp.py-7.0.0/stomp/protocol.py        1980-01-01 01:00:00.000000000 
+0100
@@ -1,7 +1,6 @@
 """Provides the 1.0, 1.1 and 1.2 protocol classes.
 """
 
-import stomp.utils as utils
 from stomp.exception import ConnectFailedException
 from stomp.listener import *
 
@@ -13,7 +12,8 @@
     Most users should not instantiate the protocol directly. See 
:py:mod:`stomp.connect` for connection classes.
 
     :param transport:
-    :param bool auto_content_length: Whether to calculate and send the 
content-length header automatically if it has not been set
+    :param bool auto_content_length: Whether to calculate and send the 
content-length header
+    automatically if it has not been set
     """
     def __init__(self, transport, auto_content_length=True):
         self.transport = transport
@@ -21,7 +21,7 @@
         transport.set_listener("protocol-listener", self)
         self.version = "1.0"
 
-    def send_frame(self, cmd, headers=None, body=''):
+    def send_frame(self, cmd, headers=None, body=""):
         """
         Encode and send a stomp frame
         through the underlying transport.
@@ -206,8 +206,10 @@
 
     :param transport:
     :param (int,int) heartbeats:
-    :param bool auto_content_length: Whether to calculate and send the 
content-length header automatically if it has not been set
-    :param float heart_beat_receive_scale: how long to wait for a heartbeat 
before timing out, as a scale factor of receive time
+    :param bool auto_content_length: Whether to calculate and send the 
content-length header
+    automatically if it has not been set
+    :param float heart_beat_receive_scale: how long to wait for a heartbeat 
before timing out,
+    as a scale factor of receive time
     """
     def __init__(self, transport, heartbeats=(0, 0), auto_content_length=True, 
heart_beat_receive_scale=1.5):
         HeartbeatListener.__init__(self, transport, heartbeats, 
heart_beat_receive_scale)
@@ -227,7 +229,7 @@
                 pass
             headers[key] = val
 
-    def send_frame(self, cmd, headers=None, body=''):
+    def send_frame(self, cmd, headers=None, body=""):
         """
         Encode and send a stomp frame
         through the underlying transport:
@@ -377,9 +379,11 @@
 
     def send(self, destination, body, content_type=None, headers=None, 
**keyword_headers):
         """
-        Send a message to a destination in the messaging system (as per 
https://stomp.github.io/stomp-specification-1.2.html#SEND)
+        Send a message to a destination in the messaging system (as per
+         https://stomp.github.io/stomp-specification-1.2.html#SEND)
 
-        :param str destination: the destination (such as a message queue - for 
example '/queue/test' - or a message topic)
+        :param str destination: the destination (such as a message queue - for 
example
+        '/queue/test' - or a message topic)
         :param body: the content of the message
         :param str content_type: the MIME type of message
         :param dict headers: additional headers to send in the message frame
@@ -401,7 +405,8 @@
 
         :param str destination: the topic or queue to subscribe to
         :param str id: the identifier to uniquely identify the subscription
-        :param str ack: either auto, client or client-individual (see 
https://stomp.github.io/stomp-specification-1.2.html#SUBSCRIBE for more info)
+        :param str ack: either auto, client or client-individual
+        (see https://stomp.github.io/stomp-specification-1.2.html#SUBSCRIBE 
for more info)
         :param dict headers: a map of any additional headers to send with the 
subscription
         :param keyword_headers: any additional headers to send with the 
subscription
         """
@@ -435,11 +440,14 @@
 
     :param transport:
     :param (int,int) heartbeats:
-    :param bool auto_content_length: Whether to calculate and send the 
content-length header automatically if it has not been set
-    :param float heart_beat_receive_scale: how long to wait for a heartbeat 
before timing out, as a scale factor of receive time
+    :param bool auto_content_length: Whether to calculate and send the 
content-length header
+    automatically if it has not been set
+    :param float heart_beat_receive_scale: how long to wait for a heartbeat 
before timing out,
+    as a scale factor of receive time
     """
     def __init__(self, transport, heartbeats=(0, 0), auto_content_length=True, 
heart_beat_receive_scale=1.5):
-        Protocol11.__init__(self, transport, heartbeats, auto_content_length, 
heart_beat_receive_scale=heart_beat_receive_scale)
+        Protocol11.__init__(self, transport, heartbeats, auto_content_length,
+                            heart_beat_receive_scale=heart_beat_receive_scale)
         self.version = "1.2"
 
     def _escape_headers(self, headers):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/transport.py 
new/stomp.py-7.0.0/stomp/transport.py
--- old/stomp.py-6.1.0/stomp/transport.py       2020-04-13 13:32:44.547436700 
+0200
+++ new/stomp.py-7.0.0/stomp/transport.py       1980-01-01 01:00:00.000000000 
+0100
@@ -1,4 +1,5 @@
-"""Provides the underlying transport functionality (for stomp message 
transmission) - (mostly) independent from the actual STOMP protocol
+"""Provides the underlying transport functionality (for stomp message 
transmission) - (mostly) independent
+from the actual STOMP protocol
 """
 
 import errno
@@ -18,9 +19,11 @@
 except (ImportError, AttributeError):
     ssl = None
 
+
     class SSLError(object):
         pass
 
+
     DEFAULT_SSL_VERSION = None
 
 try:
@@ -55,18 +58,19 @@
     __content_length_re = 
re.compile(b"^content-length[:]\\s*(?P<value>[0-9]+)", re.MULTILINE)
 
     def __init__(self, auto_decode=True, encoding="utf-8", 
is_eol_fc=is_eol_default):
-        self.__recvbuf = b''
+        self.__recvbuf = b""
         self.listeners = {}
         self.running = False
         self.blocking = None
         self.connected = False
         self.connection_error = False
+        self.disconnecting = False
         self.__receipts = {}
         self.current_host_and_port = None
-
+        self.bind_host_port = None
         # flag used when we receive the disconnect receipt
         self.__disconnect_receipt = None
-        self.__notified_on_disconnect = False
+        self.notified_on_disconnect = False
 
         # function for creating threads used by the connection
         self.create_thread_fc = default_create_thread
@@ -129,6 +133,7 @@
         with self.__connect_wait_condition:
             self.connected = connected
             if connected:
+                self.disconnecting = False
                 self.__connect_wait_condition.notify()
 
     def set_receipt(self, receipt_id, value):
@@ -180,26 +185,25 @@
         frame_type = f.cmd.lower()
         if frame_type in ["connected", "message", "receipt", "error", 
"heartbeat"]:
             if frame_type == "message":
-                (f.headers, f.body) = self.notify("before_message", f.headers, 
f.body)
+                self.notify("before_message", f)
             if logging.isEnabledFor(logging.DEBUG):
                 logging.debug("Received frame: %r, headers=%r, body=%r", 
f.cmd, f.headers, f.body)
             else:
                 logging.info("Received frame: %r, len(body)=%r", f.cmd, 
length(f.body))
-            self.notify(frame_type, f.headers, f.body)
+            self.notify(frame_type, f)
         else:
             logging.warning("Unknown response frame type: '%s' (frame length 
was %d)", frame_type, length(frame_str))
 
-    def notify(self, frame_type, headers=None, body=None):
+    def notify(self, frame_type, frame=None):
         """
         Utility function for notifying listeners of incoming and outgoing 
messages
 
         :param str frame_type: the type of message
-        :param dict headers: the map of headers associated with the message
-        :param body: the content of the message
+        :param Frame frame: the stomp frame
         """
         if frame_type == "receipt":
             # logic for wait-on-receipt notification
-            receipt = headers["receipt-id"]
+            receipt = frame.headers["receipt-id"]
             receipt_value = self.__receipts.get(receipt)
             with self.__send_wait_condition:
                 self.set_receipt(receipt, None)
@@ -216,7 +220,7 @@
             self.set_connected(True)
 
         elif frame_type == "disconnected":
-            self.__notified_on_disconnect = True
+            self.notified_on_disconnect = True
             self.set_connected(False)
 
         with self.__listeners_change_condition:
@@ -239,10 +243,7 @@
                     self.connection_error = True
                     self.__connect_wait_condition.notify()
 
-            rtn = notify_func(headers, body)
-            if rtn:
-                (headers, body) = rtn
-        return (headers, body)
+            notify_func(frame)
 
     def transmit(self, frame):
         """
@@ -348,7 +349,7 @@
                         #
                         # Clear out any half-received messages after losing 
connection
                         #
-                        self.__recvbuf = b''
+                        self.__recvbuf = b""
                         self.running = False
                         notify_disconnected = True
                     break
@@ -360,10 +361,11 @@
                 self.__receiver_thread_exit_condition.notifyAll()
             logging.info("Receiver loop ended")
             self.notify("receiver_loop_completed")
-            if notify_disconnected and not self.__notified_on_disconnect:
+            if notify_disconnected and not self.notified_on_disconnect:
                 self.notify("disconnected")
             with self.__connect_wait_condition:
                 self.__connect_wait_condition.notifyAll()
+            self.notified_on_disconnect = False
 
     def __read(self):
         """
@@ -381,8 +383,8 @@
                     logging.debug("socket read interrupted, restarting")
                     continue
             except Exception:
-                logging.debug("socket read error", exc_info=True)
-                c = b''
+                logging.debug("socket read error", exc_info=logging.verbose)
+                c = b""
             if c is None or len(c) == 0:
                 logging.debug("nothing received, raising CCE")
                 raise exception.ConnectionClosedException()
@@ -396,7 +398,7 @@
                 fastbuf.close()
                 return [c]
             fastbuf.write(c)
-            if b'\x00' in c:
+            if b"\x00" in c:
                 #
                 # Possible end of frame
                 #
@@ -407,7 +409,7 @@
 
         if self.__recvbuf and self.running:
             while True:
-                pos = self.__recvbuf.find(b'\x00')
+                pos = self.__recvbuf.find(b"\x00")
 
                 if pos >= 0:
                     frame = self.__recvbuf[0:pos]
@@ -515,11 +517,12 @@
                  auto_decode=True,
                  encoding="utf-8",
                  recv_bytes=1024,
-                 is_eol_fc=is_eol_default
-                 ):
+                 is_eol_fc=is_eol_default,
+                 bind_host_port=None):
         BaseTransport.__init__(self, auto_decode, encoding, is_eol_fc)
 
         if host_and_ports is None:
+            logging.debug("No hosts_and_ports specified, adding default 
localhost")
             host_and_ports = [("localhost", 61613)]
 
         sorted_host_and_ports = []
@@ -542,7 +545,8 @@
             for host_and_port in sorted_host_and_ports:
                 if is_localhost(host_and_port) == 1:
                     port = host_and_port[1]
-                    if not (("127.0.0.1", port) in sorted_host_and_ports or 
("localhost", port) in sorted_host_and_ports):
+                    if not (("127.0.0.1", port) in sorted_host_and_ports or (
+                    "localhost", port) in sorted_host_and_ports):
                         loopback_host_and_ports.append(("127.0.0.1", port))
 
         #
@@ -551,6 +555,7 @@
         self.__host_and_ports = []
         self.__host_and_ports.extend(loopback_host_and_ports)
         self.__host_and_ports.extend(sorted_host_and_ports)
+        self.__bind_host_port = bind_host_port
 
         self.__reconnect_sleep_initial = reconnect_sleep_initial
         self.__reconnect_sleep_increase = reconnect_sleep_increase
@@ -628,7 +633,8 @@
                 logging.warning("Unable to close socket because of error 
'%s'", e)
         self.current_host_and_port = None
         self.socket = None
-        self.notify("disconnected")
+        if not self.notified_on_disconnect:
+            self.notify("disconnected")
 
     def send(self, encoded_frame):
         """
@@ -640,7 +646,7 @@
                     self.socket.sendall(encoded_frame)
             except Exception:
                 _, e, _ = sys.exc_info()
-                logging.error("Error sending frame", exc_info=1)
+                logging.error("Error sending frame", exc_info=True)
                 raise e
         else:
             raise exception.NotConnectedException()
@@ -728,13 +734,15 @@
         connect_count = 0
 
         logging.info("attempt reconnection (%s, %s, %s)", self.running, 
self.socket, connect_count)
-        while self.running and self.socket is None and (
-            connect_count < self.__reconnect_attempts_max or
-            self.__reconnect_attempts_max == -1 ):
+        while self.running and self.socket is None and (connect_count < 
self.__reconnect_attempts_max or
+                                                        
self.__reconnect_attempts_max == -1):
             for host_and_port in self.__host_and_ports:
                 try:
                     logging.info("Attempting connection to host %s, port %s", 
host_and_port[0], host_and_port[1])
-                    self.socket = socket.create_connection(host_and_port, 
self.__timeout)
+                    if self.__bind_host_port:
+                        self.socket = socket.create_connection(host_and_port, 
self.__timeout, self.__bind_host_port)
+                    else:
+                        self.socket = socket.create_connection(host_and_port, 
self.__timeout)
                     self.__enable_keepalive()
                     need_ssl = self.__need_ssl(host_and_port)
 
@@ -791,7 +799,8 @@
                 except socket.error:
                     self.socket = None
                     connect_count += 1
-                    logging.warning("Could not connect to host %s, port %s", 
host_and_port[0], host_and_port[1], exc_info=1)
+                    logging.warning("Could not connect to host %s, port %s", 
host_and_port[0], host_and_port[1],
+                                    exc_info=logging.verbose)
 
             if self.socket is None:
                 sleep_duration = (min(self.__reconnect_sleep_max,
@@ -834,6 +843,7 @@
                                as returned by ssl.SSLSocket.getpeercert()
         :param ssl_version: SSL protocol to use for the connection. This 
should be one of the PROTOCOL_x
                             constants provided by the ssl module. The default 
is ssl.PROTOCOL_TLSv1
+        :param password: SSL password
         """
         if not ssl:
             raise Exception("SSL connection requested, but SSL library not 
found")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/stomp.py-6.1.0/stomp/utils.py 
new/stomp.py-7.0.0/stomp/utils.py
--- old/stomp.py-6.1.0/stomp/utils.py   2020-04-13 13:32:44.547436700 +0200
+++ new/stomp.py-7.0.0/stomp/utils.py   1980-01-01 01:00:00.000000000 +0100
@@ -16,7 +16,7 @@
 # preferred targets.
 LOCALHOST_NAMES = ["localhost", "127.0.0.1"]
 
-NULL = b'\x00'
+NULL = b"\x00"
 
 if not os.environ.get("STOMP_SKIP_HOSTNAME_SCAN"):
     try:
@@ -40,6 +40,7 @@
     Decode the byte data to a string if not None.
 
     :param bytes byte_data: the data to decode
+    :param string encoding: character encoding
 
     :rtype: str
     """
@@ -53,6 +54,7 @@
     Encode the parameter as a byte string.
 
     :param char_data: the data to encode
+    :param string encoding: character encoding
 
     :rtype: bytes
     """
@@ -72,7 +74,7 @@
 
     :rtype: bytes
     """
-    return b''.join(pieces)
+    return b"".join(pieces)
 
 
 def join(chars=()):
@@ -83,11 +85,12 @@
 
     :rtype: str
     """
-    return b''.join(chars).decode()
+    return b"".join(chars).decode()
 
 
 def is_eol_default(c):
-    return c == b'\x0a'
+    return c == b"\x0a"
+
 
 ##
 # Used to parse STOMP header lines in the format "key:value",
@@ -143,10 +146,10 @@
 
 
 _HEADER_ESCAPES = {
-    '\r': '\\r',
-    '\n': '\\n',
-    ':': '\\c',
-    '\\': '\\\\',
+    "\r": "\\r",
+    "\n": "\\n",
+    ":": "\\c",
+    "\\": "\\\\",
 }
 _HEADER_UNESCAPES = dict((value, key) for (key, value) in 
_HEADER_ESCAPES.items())
 
@@ -174,10 +177,10 @@
         header_match = HEADER_LINE_RE.match(header_line)
         if header_match:
             key = header_match.group("key")
-            key = re.sub(r'\\.', _unescape_header, key)
+            key = re.sub(r"\\.", _unescape_header, key)
             if key not in headers:
                 value = header_match.group("value")
-                value = re.sub(r'\\.', _unescape_header, value)
+                value = re.sub(r"\\.", _unescape_header, value)
                 headers[key] = value
     return headers
 
@@ -190,7 +193,6 @@
 
     :rtype: Frame
     """
-    f = Frame()
     mat = PREAMBLE_END_RE.search(frame)
     if mat:
         preamble_end = mat.start()
@@ -201,7 +203,7 @@
     preamble = decode(frame[0:preamble_end])
     preamble_lines = LINE_END_RE.split(preamble)
     preamble_len = len(preamble_lines)
-    f.body = frame[body_start:]
+    body = frame[body_start:]
 
     # Skip any leading newlines
     first_line = 0
@@ -212,12 +214,12 @@
         return None
 
     # Extract frame type/command
-    f.cmd = preamble_lines[first_line]
+    cmd = preamble_lines[first_line]
 
     # Put headers into a key/value map
-    f.headers = parse_headers(preamble_lines, first_line + 1)
+    headers = parse_headers(preamble_lines, first_line + 1)
 
-    return f
+    return Frame(cmd, headers, body)
 
 
 def merge_headers(header_map_list):
@@ -262,9 +264,9 @@
     (cx, cy) = chb
     x = 0
     y = 0
-    if cx != 0 and sy != '0':
+    if cx != 0 and sy != "0":
         x = max(cx, int(sy))
-    if cy != 0 and sx != '0':
+    if cy != 0 and sx != "0":
         y = max(cy, int(sx))
     return x, y
 
@@ -326,9 +328,10 @@
     :param dict headers: a map of headers for the frame
     :param body: the content of the frame.
     """
-    def __init__(self, cmd=None, headers=None, body=None):
+    def __init__(self, cmd, headers=None, body=None):
         self.cmd = cmd
         self.headers = headers if headers is not None else {}
+        self.original_headers = copy.copy(self.headers)
         self.body = body
 
     def __str__(self):
@@ -351,4 +354,4 @@
         return e.args[0]
 
 
-HEARTBEAT_FRAME = Frame("heartbeat")
\ No newline at end of file
+HEARTBEAT_FRAME = Frame("heartbeat")

Reply via email to