Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-amqp for openSUSE:Factory 
checked in at 2021-12-21 18:40:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-amqp (Old)
 and      /work/SRC/openSUSE:Factory/.python-amqp.new.2520 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-amqp"

Tue Dec 21 18:40:16 2021 rev:38 rq:941637 version:5.0.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-amqp/python-amqp.changes  2021-07-10 
22:53:34.864185233 +0200
+++ /work/SRC/openSUSE:Factory/.python-amqp.new.2520/python-amqp.changes        
2021-12-21 18:40:18.321856269 +0100
@@ -1,0 +2,10 @@
+Mon Dec 20 11:07:31 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 5.0.8:
+  - Reduce memory usage of Connection (#377)
+  - Add additional error handling around code where an OSError 
+    may be raised on failed connections. Fixes (#378)
+  - Remove dependency to case
+  - Bugfix: not closing socket after server disconnect 
+
+-------------------------------------------------------------------

Old:
----
  amqp-5.0.6.tar.gz

New:
----
  amqp-5.0.8.tar.gz

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

Other differences:
------------------
++++++ python-amqp.spec ++++++
--- /var/tmp/diff_new_pack.tGai9G/_old  2021-12-21 18:40:18.873856764 +0100
+++ /var/tmp/diff_new_pack.tGai9G/_new  2021-12-21 18:40:18.881856771 +0100
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-amqp
-Version:        5.0.6
+Version:        5.0.8
 Release:        0
 Summary:        Low-level AMQP client for Python (fork of amqplib)
 License:        LGPL-2.1-or-later

++++++ amqp-5.0.6.tar.gz -> amqp-5.0.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/Changelog new/amqp-5.0.8/Changelog
--- old/amqp-5.0.6/Changelog    2021-04-01 06:40:10.000000000 +0200
+++ new/amqp-5.0.8/Changelog    2021-12-19 06:01:33.000000000 +0100
@@ -5,6 +5,30 @@
 The previous amqplib changelog is here:
 http://code.google.com/p/py-amqplib/source/browse/CHANGES
 
+
+.. _version-5.0.8:
+
+5.0.8
+=====
+:release-date: 2021-12-19 11:15 A.M. UTC+6:00
+:release-by: Asif Saif Uddin
+
+- Reduce memory usage of Connection (#377)
+- Add additional error handling around code where an OSError 
+  may be raised on failed connections. Fixes (#378)
+
+
+.. _version-5.0.7:
+
+5.0.7
+=====
+:release-date: 2021-12-13 15:45 P.M. UTC+6:00
+:release-by: Asif Saif Uddin
+
+- Remove dependency to case
+- Bugfix: not closing socket after server disconnect 
+
+
 .. _version-5.0.6:
 
 5.0.6
@@ -167,7 +191,7 @@
 :release-by: Asif Saif Uddin
 
 - Fix buffer overflow in frame_writer after frame_max is increased. 
`frame_writer`
-allocates a `bytearray` on intialization with a length based on the 
`connection.frame_max`
+allocates a `bytearray` on initialization with a length based on the 
`connection.frame_max`
 value. If `connection.frame_max` is changed to a larger value, this causes an
 error like `pack_into requires a buffer of at least 408736 bytes`.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/PKG-INFO new/amqp-5.0.8/PKG-INFO
--- old/amqp-5.0.6/PKG-INFO     2021-04-01 08:11:48.080170400 +0200
+++ new/amqp-5.0.8/PKG-INFO     2021-12-19 06:06:23.980194600 +0100
@@ -1,223 +1,12 @@
 Metadata-Version: 2.1
 Name: amqp
-Version: 5.0.6
+Version: 5.0.8
 Summary: Low-level AMQP client for Python (fork of amqplib).
 Home-page: http://github.com/celery/py-amqp
 Author: Barry Pederson
 Author-email: pya...@celeryproject.org
 Maintainer: Asif Saif Uddin, Matus Valo
 License: BSD
-Description: 
=====================================================================
-         Python AMQP 0.9.1 client library
-        =====================================================================
-        
-        |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
-        
-        :Version: 5.0.6
-        :Web: https://amqp.readthedocs.io/
-        :Download: https://pypi.org/project/amqp/
-        :Source: http://github.com/celery/py-amqp/
-        :Keywords: amqp, rabbitmq
-        
-        About
-        =====
-        
-        This is a fork of amqplib_ which was originally written by Barry 
Pederson.
-        It is maintained by the Celery_ project, and used by `kombu`_ as a 
pure python
-        alternative when `librabbitmq`_ is not available.
-        
-        This library should be API compatible with `librabbitmq`_.
-        
-        .. _amqplib: https://pypi.org/project/amqplib/
-        .. _Celery: http://celeryproject.org/
-        .. _kombu: https://kombu.readthedocs.io/
-        .. _librabbitmq: https://pypi.org/project/librabbitmq/
-        
-        Differences from `amqplib`_
-        ===========================
-        
-        - Supports draining events from multiple channels 
(``Connection.drain_events``)
-        - Support for timeouts
-        - Channels are restored after channel error, instead of having to 
close the
-          connection.
-        - Support for heartbeats
-        
-            - ``Connection.heartbeat_tick(rate=2)`` must called at regular 
intervals
-              (half of the heartbeat value if rate is 2).
-            - Or some other scheme by using ``Connection.send_heartbeat``.
-        - Supports RabbitMQ extensions:
-            - Consumer Cancel Notifications
-                - by default a cancel results in ``ChannelError`` being raised
-                - but not if a ``on_cancel`` callback is passed to 
``basic_consume``.
-            - Publisher confirms
-                - ``Channel.confirm_select()`` enables publisher confirms.
-                - ``Channel.events['basic_ack'].append(my_callback)`` adds a 
callback
-                  to be called when a message is confirmed. This callback is 
then
-                  called with the signature ``(delivery_tag, multiple)``.
-            - Exchange-to-exchange bindings: ``exchange_bind`` / 
``exchange_unbind``.
-                - ``Channel.confirm_select()`` enables publisher confirms.
-                - ``Channel.events['basic_ack'].append(my_callback)`` adds a 
callback
-                  to be called when a message is confirmed. This callback is 
then
-                  called with the signature ``(delivery_tag, multiple)``.
-            - Authentication Failure Notifications
-                Instead of just closing the connection abruptly on invalid
-                credentials, py-amqp will raise an ``AccessRefused`` error
-                when connected to rabbitmq-server 3.2.0 or greater.
-        - Support for ``basic_return``
-        - Uses AMQP 0-9-1 instead of 0-8.
-            - ``Channel.access_request`` and ``ticket`` arguments to methods
-              **removed**.
-            - Supports the ``arguments`` argument to ``basic_consume``.
-            - ``internal`` argument to ``exchange_declare`` removed.
-            - ``auto_delete`` argument to ``exchange_declare`` deprecated
-            - ``insist`` argument to ``Connection`` removed.
-            - ``Channel.alerts`` has been removed.
-            - Support for ``Channel.basic_recover_async``.
-            - ``Channel.basic_recover`` deprecated.
-        - Exceptions renamed to have idiomatic names:
-            - ``AMQPException`` -> ``AMQPError``
-            - ``AMQPConnectionException`` -> ConnectionError``
-            - ``AMQPChannelException`` -> ChannelError``
-            - ``Connection.known_hosts`` removed.
-            - ``Connection`` no longer supports redirects.
-            - ``exchange`` argument to ``queue_bind`` can now be empty
-              to use the "default exchange".
-        - Adds ``Connection.is_alive`` that tries to detect
-          whether the connection can still be used.
-        - Adds ``Connection.connection_errors`` and ``.channel_errors``,
-          a list of recoverable errors.
-        - Exposes the underlying socket as ``Connection.sock``.
-        - Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
-          that set the no_ack flag.
-        - Slightly better at error recovery
-        
-        Quick overview
-        ==============
-        
-        Simple producer publishing messages to ``test`` queue using default 
exchange:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection('broker.example.com') as c:
-                ch = c.channel()
-                ch.basic_publish(amqp.Message('Hello World'), 
routing_key='test')
-        
-        Producer publishing to ``test_exchange`` exchange with publisher 
confirms enabled and using virtual_host ``test_vhost``:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection(
-                'broker.example.com', exchange='test_exchange',
-                confirm_publish=True, virtual_host='test_vhost'
-            ) as c:
-                ch = c.channel()
-                ch.basic_publish(amqp.Message('Hello World'), 
routing_key='test')
-        
-        Consumer with acknowledgments enabled:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection('broker.example.com') as c:
-                ch = c.channel()
-                def on_message(message):
-                    print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
-                    ch.basic_ack(message.delivery_tag)
-                ch.basic_consume(queue='test', callback=on_message)
-                while True:
-                    c.drain_events()
-        
-        
-        Consumer with acknowledgments disabled:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection('broker.example.com') as c:
-                ch = c.channel()
-                def on_message(message):
-                    print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
-                ch.basic_consume(queue='test', callback=on_message, 
no_ack=True)
-                while True:
-                    c.drain_events()
-        
-        Speedups
-        ========
-        
-        This library has **experimental** support of speedups. Speedups are 
implemented using Cython. To enable speedups, ``CELERY_ENABLE_SPEEDUPS`` 
environment variable must be set during building/installation.
-        Currently speedups can be installed:
-        
-        1. using source package (using ``--no-binary`` switch):
-        
-        .. code:: shell
-        
-            CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
-        
-        
-        2. building directly source code:
-        
-        .. code:: shell
-        
-            CELERY_ENABLE_SPEEDUPS=true python setup.py install
-        
-        Further
-        =======
-        
-        - Differences between AMQP 0.8 and 0.9.1
-        
-            http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
-        
-        - AMQP 0.9.1 Quick Reference
-        
-            http://www.rabbitmq.com/amqp-0-9-1-quickref.html
-        
-        - RabbitMQ Extensions
-        
-            http://www.rabbitmq.com/extensions.html
-        
-        - For more information about AMQP, visit
-        
-            http://www.amqp.org
-        
-        - For other Python client libraries see:
-        
-            http://www.rabbitmq.com/devtools.html#python-dev
-        
-        .. |build-status| image:: 
https://api.travis-ci.com/celery/py-amqp.png?branch=master
-            :alt: Build status
-            :target: https://travis-ci.com/celery/py-amqp
-        
-        .. |coverage| image:: 
https://codecov.io/github/celery/py-amqp/coverage.svg?branch=master
-            :target: https://codecov.io/github/celery/py-amqp?branch=master
-        
-        .. |license| image:: https://img.shields.io/pypi/l/amqp.svg
-            :alt: BSD License
-            :target: https://opensource.org/licenses/BSD-3-Clause
-        
-        .. |wheel| image:: https://img.shields.io/pypi/wheel/amqp.svg
-            :alt: Python AMQP can be installed via wheel
-            :target: https://pypi.org/project/amqp/
-        
-        .. |pyversion| image:: https://img.shields.io/pypi/pyversions/amqp.svg
-            :alt: Supported Python versions.
-            :target: https://pypi.org/project/amqp/
-        
-        .. |pyimp| image:: https://img.shields.io/pypi/implementation/amqp.svg
-            :alt: Support Python implementations.
-            :target: https://pypi.org/project/amqp/
-            
-        py-amqp as part of the Tidelift Subscription
-        ============================================
-        
-        The maintainers of py-amqp and thousands of other packages are working 
with Tidelift to deliver commercial support and maintenance for the open source 
dependencies you use to build your applications. Save time, reduce risk, and 
improve code health, while paying the maintainers of the exact dependencies you 
use. [Learn 
more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
-        
-        
 Keywords: amqp rabbitmq cloudamqp messaging
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
@@ -227,6 +16,8 @@
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: BSD License
@@ -234,3 +25,217 @@
 Classifier: Operating System :: OS Independent
 Requires-Python: >=3.6
 Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+=====================================================================
+ Python AMQP 0.9.1 client library
+=====================================================================
+
+|build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
+
+:Version: 5.0.8
+:Web: https://amqp.readthedocs.io/
+:Download: https://pypi.org/project/amqp/
+:Source: http://github.com/celery/py-amqp/
+:Keywords: amqp, rabbitmq
+
+About
+=====
+
+This is a fork of amqplib_ which was originally written by Barry Pederson.
+It is maintained by the Celery_ project, and used by `kombu`_ as a pure python
+alternative when `librabbitmq`_ is not available.
+
+This library should be API compatible with `librabbitmq`_.
+
+.. _amqplib: https://pypi.org/project/amqplib/
+.. _Celery: http://celeryproject.org/
+.. _kombu: https://kombu.readthedocs.io/
+.. _librabbitmq: https://pypi.org/project/librabbitmq/
+
+Differences from `amqplib`_
+===========================
+
+- Supports draining events from multiple channels (``Connection.drain_events``)
+- Support for timeouts
+- Channels are restored after channel error, instead of having to close the
+  connection.
+- Support for heartbeats
+
+    - ``Connection.heartbeat_tick(rate=2)`` must called at regular intervals
+      (half of the heartbeat value if rate is 2).
+    - Or some other scheme by using ``Connection.send_heartbeat``.
+- Supports RabbitMQ extensions:
+    - Consumer Cancel Notifications
+        - by default a cancel results in ``ChannelError`` being raised
+        - but not if a ``on_cancel`` callback is passed to ``basic_consume``.
+    - Publisher confirms
+        - ``Channel.confirm_select()`` enables publisher confirms.
+        - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
+          to be called when a message is confirmed. This callback is then
+          called with the signature ``(delivery_tag, multiple)``.
+    - Exchange-to-exchange bindings: ``exchange_bind`` / ``exchange_unbind``.
+        - ``Channel.confirm_select()`` enables publisher confirms.
+        - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
+          to be called when a message is confirmed. This callback is then
+          called with the signature ``(delivery_tag, multiple)``.
+    - Authentication Failure Notifications
+        Instead of just closing the connection abruptly on invalid
+        credentials, py-amqp will raise an ``AccessRefused`` error
+        when connected to rabbitmq-server 3.2.0 or greater.
+- Support for ``basic_return``
+- Uses AMQP 0-9-1 instead of 0-8.
+    - ``Channel.access_request`` and ``ticket`` arguments to methods
+      **removed**.
+    - Supports the ``arguments`` argument to ``basic_consume``.
+    - ``internal`` argument to ``exchange_declare`` removed.
+    - ``auto_delete`` argument to ``exchange_declare`` deprecated
+    - ``insist`` argument to ``Connection`` removed.
+    - ``Channel.alerts`` has been removed.
+    - Support for ``Channel.basic_recover_async``.
+    - ``Channel.basic_recover`` deprecated.
+- Exceptions renamed to have idiomatic names:
+    - ``AMQPException`` -> ``AMQPError``
+    - ``AMQPConnectionException`` -> ConnectionError``
+    - ``AMQPChannelException`` -> ChannelError``
+    - ``Connection.known_hosts`` removed.
+    - ``Connection`` no longer supports redirects.
+    - ``exchange`` argument to ``queue_bind`` can now be empty
+      to use the "default exchange".
+- Adds ``Connection.is_alive`` that tries to detect
+  whether the connection can still be used.
+- Adds ``Connection.connection_errors`` and ``.channel_errors``,
+  a list of recoverable errors.
+- Exposes the underlying socket as ``Connection.sock``.
+- Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
+  that set the no_ack flag.
+- Slightly better at error recovery
+
+Quick overview
+==============
+
+Simple producer publishing messages to ``test`` queue using default exchange:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection('broker.example.com') as c:
+        ch = c.channel()
+        ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
+
+Producer publishing to ``test_exchange`` exchange with publisher confirms 
enabled and using virtual_host ``test_vhost``:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection(
+        'broker.example.com', exchange='test_exchange',
+        confirm_publish=True, virtual_host='test_vhost'
+    ) as c:
+        ch = c.channel()
+        ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
+
+Consumer with acknowledgments enabled:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection('broker.example.com') as c:
+        ch = c.channel()
+        def on_message(message):
+            print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
+            ch.basic_ack(message.delivery_tag)
+        ch.basic_consume(queue='test', callback=on_message)
+        while True:
+            c.drain_events()
+
+
+Consumer with acknowledgments disabled:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection('broker.example.com') as c:
+        ch = c.channel()
+        def on_message(message):
+            print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
+        ch.basic_consume(queue='test', callback=on_message, no_ack=True)
+        while True:
+            c.drain_events()
+
+Speedups
+========
+
+This library has **experimental** support of speedups. Speedups are 
implemented using Cython. To enable speedups, ``CELERY_ENABLE_SPEEDUPS`` 
environment variable must be set during building/installation.
+Currently speedups can be installed:
+
+1. using source package (using ``--no-binary`` switch):
+
+.. code:: shell
+
+    CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
+
+
+2. building directly source code:
+
+.. code:: shell
+
+    CELERY_ENABLE_SPEEDUPS=true python setup.py install
+
+Further
+=======
+
+- Differences between AMQP 0.8 and 0.9.1
+
+    http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
+
+- AMQP 0.9.1 Quick Reference
+
+    http://www.rabbitmq.com/amqp-0-9-1-quickref.html
+
+- RabbitMQ Extensions
+
+    http://www.rabbitmq.com/extensions.html
+
+- For more information about AMQP, visit
+
+    http://www.amqp.org
+
+- For other Python client libraries see:
+
+    http://www.rabbitmq.com/devtools.html#python-dev
+
+.. |build-status| image:: 
https://api.travis-ci.com/celery/py-amqp.png?branch=master
+    :alt: Build status
+    :target: https://travis-ci.com/celery/py-amqp
+
+.. |coverage| image:: 
https://codecov.io/github/celery/py-amqp/coverage.svg?branch=master
+    :target: https://codecov.io/github/celery/py-amqp?branch=master
+
+.. |license| image:: https://img.shields.io/pypi/l/amqp.svg
+    :alt: BSD License
+    :target: https://opensource.org/licenses/BSD-3-Clause
+
+.. |wheel| image:: https://img.shields.io/pypi/wheel/amqp.svg
+    :alt: Python AMQP can be installed via wheel
+    :target: https://pypi.org/project/amqp/
+
+.. |pyversion| image:: https://img.shields.io/pypi/pyversions/amqp.svg
+    :alt: Supported Python versions.
+    :target: https://pypi.org/project/amqp/
+
+.. |pyimp| image:: https://img.shields.io/pypi/implementation/amqp.svg
+    :alt: Support Python implementations.
+    :target: https://pypi.org/project/amqp/
+    
+py-amqp as part of the Tidelift Subscription
+============================================
+
+The maintainers of py-amqp and thousands of other packages are working with 
Tidelift to deliver commercial support and maintenance for the open source 
dependencies you use to build your applications. Save time, reduce risk, and 
improve code health, while paying the maintainers of the exact dependencies you 
use. [Learn 
more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
+
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/README.rst new/amqp-5.0.8/README.rst
--- old/amqp-5.0.6/README.rst   2021-04-01 08:10:12.000000000 +0200
+++ new/amqp-5.0.8/README.rst   2021-12-19 06:03:38.000000000 +0100
@@ -4,7 +4,7 @@
 
 |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
 
-:Version: 5.0.6
+:Version: 5.0.8
 :Web: https://amqp.readthedocs.io/
 :Download: https://pypi.org/project/amqp/
 :Source: http://github.com/celery/py-amqp/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp/__init__.py 
new/amqp-5.0.8/amqp/__init__.py
--- old/amqp-5.0.6/amqp/__init__.py     2021-04-01 06:41:46.000000000 +0200
+++ new/amqp-5.0.8/amqp/__init__.py     2021-12-19 06:02:34.000000000 +0100
@@ -4,7 +4,7 @@
 import re
 from collections import namedtuple
 
-__version__ = '5.0.6'
+__version__ = '5.0.8'
 __author__ = 'Barry Pederson'
 __maintainer__ = 'Asif Saif Uddin, Matus Valo'
 __contact__ = 'pya...@celeryproject.org'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp/abstract_channel.py 
new/amqp-5.0.8/amqp/abstract_channel.py
--- old/amqp-5.0.6/amqp/abstract_channel.py     2021-01-28 17:38:45.000000000 
+0100
+++ new/amqp-5.0.8/amqp/abstract_channel.py     2021-12-12 06:39:32.000000000 
+0100
@@ -68,7 +68,7 @@
 
     def close(self):
         """Close this Channel or Connection."""
-        raise NotImplementedError('Must be overriden in subclass')
+        raise NotImplementedError('Must be overridden in subclass')
 
     def wait(self, method, callback=None, timeout=None, returns_tuple=False):
         p = ensure_promise(callback)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp/channel.py 
new/amqp-5.0.8/amqp/channel.py
--- old/amqp-5.0.6/amqp/channel.py      2021-04-01 06:06:58.000000000 +0200
+++ new/amqp-5.0.8/amqp/channel.py      2021-12-17 04:55:58.000000000 +0100
@@ -150,7 +150,11 @@
         connection, self.connection = self.connection, None
         if connection:
             connection.channels.pop(channel_id, None)
-            connection._avail_channel_ids.append(channel_id)
+            try:
+                connection._used_channel_ids.remove(channel_id)
+            except ValueError:
+                # channel id already removed
+                pass
         self.callbacks.clear()
         self.cancel_callbacks.clear()
         self.events.clear()
@@ -1380,7 +1384,7 @@
                 False, the delivery tag refers to a single message.
                 If the multiple field is True, and the delivery tag
                 is zero, tells the server to acknowledge all
-                outstanding mesages.
+                outstanding messages.
 
                 RULE:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp/connection.py 
new/amqp-5.0.8/amqp/connection.py
--- old/amqp-5.0.6/amqp/connection.py   2021-01-28 17:38:49.000000000 +0100
+++ new/amqp-5.0.8/amqp/connection.py   2021-12-17 04:55:58.000000000 +0100
@@ -104,7 +104,7 @@
 
     When "confirm_publish" is set to True, the channel is put to
     confirm mode. In this mode, each published message is
-    confirmed using Publisher confirms RabbitMQ extention.
+    confirmed using Publisher confirms RabbitMQ extension.
     """
 
     Channel = Channel
@@ -267,7 +267,7 @@
         self.on_unblocked = on_unblocked
         self.on_open = ensure_promise(on_open)
 
-        self._avail_channel_ids = array('H', range(self.channel_max, 0, -1))
+        self._used_channel_ids = array('H')
 
         # Properties set in the Start method
         self.version_major = 0
@@ -466,38 +466,36 @@
         return self._transport and self._transport.connected
 
     def collect(self):
-        try:
-            if self._transport:
-                self._transport.close()
+        if self._transport:
+            self._transport.close()
 
-            if self.channels:
-                # Copy all the channels except self since the channels
-                # dictionary changes during the collection process.
-                channels = [
-                    ch for ch in self.channels.values()
-                    if ch is not self
-                ]
-
-                for ch in channels:
-                    ch.collect()
-        except OSError:
-            pass  # connection already closed on the other end
-        finally:
-            self._transport = self.connection = self.channels = None
+        if self.channels:
+            # Copy all the channels except self since the channels
+            # dictionary changes during the collection process.
+            channels = [
+                ch for ch in self.channels.values()
+                if ch is not self
+            ]
+
+            for ch in channels:
+                ch.collect()
+        self._transport = self.connection = self.channels = None
 
     def _get_free_channel_id(self):
-        try:
-            return self._avail_channel_ids.pop()
-        except IndexError:
-            raise ResourceError(
-                'No free channel ids, current={}, channel_max={}'.format(
-                    len(self.channels), self.channel_max), spec.Channel.Open)
+        for channel_id in range(1, self.channel_max):
+            if channel_id not in self._used_channel_ids:
+                return channel_id
+
+        raise ResourceError(
+            'No free channel ids, current={}, channel_max={}'.format(
+                len(self.channels), self.channel_max), spec.Channel.Open)
 
     def _claim_channel_id(self, channel_id):
-        try:
-            return self._avail_channel_ids.remove(channel_id)
-        except ValueError:
+        if channel_id in self._used_channel_ids:
             raise ConnectionError(f'Channel {channel_id!r} already open')
+        else:
+            self._used_channel_ids.append(channel_id)
+            return channel_id
 
     def channel(self, channel_id=None, callback=None):
         """Create new channel.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp/transport.py 
new/amqp-5.0.8/amqp/transport.py
--- old/amqp-5.0.6/amqp/transport.py    2021-02-25 13:35:44.000000000 +0100
+++ new/amqp-5.0.8/amqp/transport.py    2021-12-17 04:55:58.000000000 +0100
@@ -256,7 +256,7 @@
 
     def _read(self, n, initial=False):
         """Read exactly n bytes from the peer."""
-        raise NotImplementedError('Must be overriden in subclass')
+        raise NotImplementedError('Must be overridden in subclass')
 
     def _setup_transport(self):
         """Do any additional initialization of the class."""
@@ -268,16 +268,27 @@
 
     def _write(self, s):
         """Completely write a string to the peer."""
-        raise NotImplementedError('Must be overriden in subclass')
+        raise NotImplementedError('Must be overridden in subclass')
 
     def close(self):
         if self.sock is not None:
-            self._shutdown_transport()
+            try:
+                self._shutdown_transport()
+            except OSError:
+                pass
+
             # Call shutdown first to make sure that pending messages
             # reach the AMQP broker if the program exits after
             # calling this method.
-            self.sock.shutdown(socket.SHUT_RDWR)
-            self.sock.close()
+            try:
+                self.sock.shutdown(socket.SHUT_RDWR)
+            except OSError:
+                pass
+
+            try:
+                self.sock.close()
+            except OSError:
+                pass
             self.sock = None
         self.connected = False
 
@@ -525,8 +536,8 @@
             context.load_verify_locations(ca_certs)
         if ciphers is not None:
             context.set_ciphers(ciphers)
-        # Set SNI headers if supported. 
-        # Must set context.check_hostname before setting context.verify_mode 
+        # Set SNI headers if supported.
+        # Must set context.check_hostname before setting context.verify_mode
         # to avoid setting context.verify_mode=ssl.CERT_NONE while
         # context.check_hostname is still True (the default value in context
         # if client-side) which results in the following exception:
@@ -539,7 +550,7 @@
         except AttributeError:
             pass  # ask forgiveness not permission
 
-        # See note above re: ordering for context.check_hostname and 
+        # See note above re: ordering for context.check_hostname and
         # context.verify_mode assignments.
         if cert_reqs is not None:
             context.verify_mode = cert_reqs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp.egg-info/PKG-INFO 
new/amqp-5.0.8/amqp.egg-info/PKG-INFO
--- old/amqp-5.0.6/amqp.egg-info/PKG-INFO       2021-04-01 08:11:47.000000000 
+0200
+++ new/amqp-5.0.8/amqp.egg-info/PKG-INFO       2021-12-19 06:06:23.000000000 
+0100
@@ -1,223 +1,12 @@
 Metadata-Version: 2.1
 Name: amqp
-Version: 5.0.6
+Version: 5.0.8
 Summary: Low-level AMQP client for Python (fork of amqplib).
 Home-page: http://github.com/celery/py-amqp
 Author: Barry Pederson
 Author-email: pya...@celeryproject.org
 Maintainer: Asif Saif Uddin, Matus Valo
 License: BSD
-Description: 
=====================================================================
-         Python AMQP 0.9.1 client library
-        =====================================================================
-        
-        |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
-        
-        :Version: 5.0.6
-        :Web: https://amqp.readthedocs.io/
-        :Download: https://pypi.org/project/amqp/
-        :Source: http://github.com/celery/py-amqp/
-        :Keywords: amqp, rabbitmq
-        
-        About
-        =====
-        
-        This is a fork of amqplib_ which was originally written by Barry 
Pederson.
-        It is maintained by the Celery_ project, and used by `kombu`_ as a 
pure python
-        alternative when `librabbitmq`_ is not available.
-        
-        This library should be API compatible with `librabbitmq`_.
-        
-        .. _amqplib: https://pypi.org/project/amqplib/
-        .. _Celery: http://celeryproject.org/
-        .. _kombu: https://kombu.readthedocs.io/
-        .. _librabbitmq: https://pypi.org/project/librabbitmq/
-        
-        Differences from `amqplib`_
-        ===========================
-        
-        - Supports draining events from multiple channels 
(``Connection.drain_events``)
-        - Support for timeouts
-        - Channels are restored after channel error, instead of having to 
close the
-          connection.
-        - Support for heartbeats
-        
-            - ``Connection.heartbeat_tick(rate=2)`` must called at regular 
intervals
-              (half of the heartbeat value if rate is 2).
-            - Or some other scheme by using ``Connection.send_heartbeat``.
-        - Supports RabbitMQ extensions:
-            - Consumer Cancel Notifications
-                - by default a cancel results in ``ChannelError`` being raised
-                - but not if a ``on_cancel`` callback is passed to 
``basic_consume``.
-            - Publisher confirms
-                - ``Channel.confirm_select()`` enables publisher confirms.
-                - ``Channel.events['basic_ack'].append(my_callback)`` adds a 
callback
-                  to be called when a message is confirmed. This callback is 
then
-                  called with the signature ``(delivery_tag, multiple)``.
-            - Exchange-to-exchange bindings: ``exchange_bind`` / 
``exchange_unbind``.
-                - ``Channel.confirm_select()`` enables publisher confirms.
-                - ``Channel.events['basic_ack'].append(my_callback)`` adds a 
callback
-                  to be called when a message is confirmed. This callback is 
then
-                  called with the signature ``(delivery_tag, multiple)``.
-            - Authentication Failure Notifications
-                Instead of just closing the connection abruptly on invalid
-                credentials, py-amqp will raise an ``AccessRefused`` error
-                when connected to rabbitmq-server 3.2.0 or greater.
-        - Support for ``basic_return``
-        - Uses AMQP 0-9-1 instead of 0-8.
-            - ``Channel.access_request`` and ``ticket`` arguments to methods
-              **removed**.
-            - Supports the ``arguments`` argument to ``basic_consume``.
-            - ``internal`` argument to ``exchange_declare`` removed.
-            - ``auto_delete`` argument to ``exchange_declare`` deprecated
-            - ``insist`` argument to ``Connection`` removed.
-            - ``Channel.alerts`` has been removed.
-            - Support for ``Channel.basic_recover_async``.
-            - ``Channel.basic_recover`` deprecated.
-        - Exceptions renamed to have idiomatic names:
-            - ``AMQPException`` -> ``AMQPError``
-            - ``AMQPConnectionException`` -> ConnectionError``
-            - ``AMQPChannelException`` -> ChannelError``
-            - ``Connection.known_hosts`` removed.
-            - ``Connection`` no longer supports redirects.
-            - ``exchange`` argument to ``queue_bind`` can now be empty
-              to use the "default exchange".
-        - Adds ``Connection.is_alive`` that tries to detect
-          whether the connection can still be used.
-        - Adds ``Connection.connection_errors`` and ``.channel_errors``,
-          a list of recoverable errors.
-        - Exposes the underlying socket as ``Connection.sock``.
-        - Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
-          that set the no_ack flag.
-        - Slightly better at error recovery
-        
-        Quick overview
-        ==============
-        
-        Simple producer publishing messages to ``test`` queue using default 
exchange:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection('broker.example.com') as c:
-                ch = c.channel()
-                ch.basic_publish(amqp.Message('Hello World'), 
routing_key='test')
-        
-        Producer publishing to ``test_exchange`` exchange with publisher 
confirms enabled and using virtual_host ``test_vhost``:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection(
-                'broker.example.com', exchange='test_exchange',
-                confirm_publish=True, virtual_host='test_vhost'
-            ) as c:
-                ch = c.channel()
-                ch.basic_publish(amqp.Message('Hello World'), 
routing_key='test')
-        
-        Consumer with acknowledgments enabled:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection('broker.example.com') as c:
-                ch = c.channel()
-                def on_message(message):
-                    print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
-                    ch.basic_ack(message.delivery_tag)
-                ch.basic_consume(queue='test', callback=on_message)
-                while True:
-                    c.drain_events()
-        
-        
-        Consumer with acknowledgments disabled:
-        
-        .. code:: python
-        
-            import amqp
-        
-            with amqp.Connection('broker.example.com') as c:
-                ch = c.channel()
-                def on_message(message):
-                    print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
-                ch.basic_consume(queue='test', callback=on_message, 
no_ack=True)
-                while True:
-                    c.drain_events()
-        
-        Speedups
-        ========
-        
-        This library has **experimental** support of speedups. Speedups are 
implemented using Cython. To enable speedups, ``CELERY_ENABLE_SPEEDUPS`` 
environment variable must be set during building/installation.
-        Currently speedups can be installed:
-        
-        1. using source package (using ``--no-binary`` switch):
-        
-        .. code:: shell
-        
-            CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
-        
-        
-        2. building directly source code:
-        
-        .. code:: shell
-        
-            CELERY_ENABLE_SPEEDUPS=true python setup.py install
-        
-        Further
-        =======
-        
-        - Differences between AMQP 0.8 and 0.9.1
-        
-            http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
-        
-        - AMQP 0.9.1 Quick Reference
-        
-            http://www.rabbitmq.com/amqp-0-9-1-quickref.html
-        
-        - RabbitMQ Extensions
-        
-            http://www.rabbitmq.com/extensions.html
-        
-        - For more information about AMQP, visit
-        
-            http://www.amqp.org
-        
-        - For other Python client libraries see:
-        
-            http://www.rabbitmq.com/devtools.html#python-dev
-        
-        .. |build-status| image:: 
https://api.travis-ci.com/celery/py-amqp.png?branch=master
-            :alt: Build status
-            :target: https://travis-ci.com/celery/py-amqp
-        
-        .. |coverage| image:: 
https://codecov.io/github/celery/py-amqp/coverage.svg?branch=master
-            :target: https://codecov.io/github/celery/py-amqp?branch=master
-        
-        .. |license| image:: https://img.shields.io/pypi/l/amqp.svg
-            :alt: BSD License
-            :target: https://opensource.org/licenses/BSD-3-Clause
-        
-        .. |wheel| image:: https://img.shields.io/pypi/wheel/amqp.svg
-            :alt: Python AMQP can be installed via wheel
-            :target: https://pypi.org/project/amqp/
-        
-        .. |pyversion| image:: https://img.shields.io/pypi/pyversions/amqp.svg
-            :alt: Supported Python versions.
-            :target: https://pypi.org/project/amqp/
-        
-        .. |pyimp| image:: https://img.shields.io/pypi/implementation/amqp.svg
-            :alt: Support Python implementations.
-            :target: https://pypi.org/project/amqp/
-            
-        py-amqp as part of the Tidelift Subscription
-        ============================================
-        
-        The maintainers of py-amqp and thousands of other packages are working 
with Tidelift to deliver commercial support and maintenance for the open source 
dependencies you use to build your applications. Save time, reduce risk, and 
improve code health, while paying the maintainers of the exact dependencies you 
use. [Learn 
more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
-        
-        
 Keywords: amqp rabbitmq cloudamqp messaging
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
@@ -227,6 +16,8 @@
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: BSD License
@@ -234,3 +25,217 @@
 Classifier: Operating System :: OS Independent
 Requires-Python: >=3.6
 Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+=====================================================================
+ Python AMQP 0.9.1 client library
+=====================================================================
+
+|build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
+
+:Version: 5.0.8
+:Web: https://amqp.readthedocs.io/
+:Download: https://pypi.org/project/amqp/
+:Source: http://github.com/celery/py-amqp/
+:Keywords: amqp, rabbitmq
+
+About
+=====
+
+This is a fork of amqplib_ which was originally written by Barry Pederson.
+It is maintained by the Celery_ project, and used by `kombu`_ as a pure python
+alternative when `librabbitmq`_ is not available.
+
+This library should be API compatible with `librabbitmq`_.
+
+.. _amqplib: https://pypi.org/project/amqplib/
+.. _Celery: http://celeryproject.org/
+.. _kombu: https://kombu.readthedocs.io/
+.. _librabbitmq: https://pypi.org/project/librabbitmq/
+
+Differences from `amqplib`_
+===========================
+
+- Supports draining events from multiple channels (``Connection.drain_events``)
+- Support for timeouts
+- Channels are restored after channel error, instead of having to close the
+  connection.
+- Support for heartbeats
+
+    - ``Connection.heartbeat_tick(rate=2)`` must called at regular intervals
+      (half of the heartbeat value if rate is 2).
+    - Or some other scheme by using ``Connection.send_heartbeat``.
+- Supports RabbitMQ extensions:
+    - Consumer Cancel Notifications
+        - by default a cancel results in ``ChannelError`` being raised
+        - but not if a ``on_cancel`` callback is passed to ``basic_consume``.
+    - Publisher confirms
+        - ``Channel.confirm_select()`` enables publisher confirms.
+        - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
+          to be called when a message is confirmed. This callback is then
+          called with the signature ``(delivery_tag, multiple)``.
+    - Exchange-to-exchange bindings: ``exchange_bind`` / ``exchange_unbind``.
+        - ``Channel.confirm_select()`` enables publisher confirms.
+        - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
+          to be called when a message is confirmed. This callback is then
+          called with the signature ``(delivery_tag, multiple)``.
+    - Authentication Failure Notifications
+        Instead of just closing the connection abruptly on invalid
+        credentials, py-amqp will raise an ``AccessRefused`` error
+        when connected to rabbitmq-server 3.2.0 or greater.
+- Support for ``basic_return``
+- Uses AMQP 0-9-1 instead of 0-8.
+    - ``Channel.access_request`` and ``ticket`` arguments to methods
+      **removed**.
+    - Supports the ``arguments`` argument to ``basic_consume``.
+    - ``internal`` argument to ``exchange_declare`` removed.
+    - ``auto_delete`` argument to ``exchange_declare`` deprecated
+    - ``insist`` argument to ``Connection`` removed.
+    - ``Channel.alerts`` has been removed.
+    - Support for ``Channel.basic_recover_async``.
+    - ``Channel.basic_recover`` deprecated.
+- Exceptions renamed to have idiomatic names:
+    - ``AMQPException`` -> ``AMQPError``
+    - ``AMQPConnectionException`` -> ConnectionError``
+    - ``AMQPChannelException`` -> ChannelError``
+    - ``Connection.known_hosts`` removed.
+    - ``Connection`` no longer supports redirects.
+    - ``exchange`` argument to ``queue_bind`` can now be empty
+      to use the "default exchange".
+- Adds ``Connection.is_alive`` that tries to detect
+  whether the connection can still be used.
+- Adds ``Connection.connection_errors`` and ``.channel_errors``,
+  a list of recoverable errors.
+- Exposes the underlying socket as ``Connection.sock``.
+- Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
+  that set the no_ack flag.
+- Slightly better at error recovery
+
+Quick overview
+==============
+
+Simple producer publishing messages to ``test`` queue using default exchange:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection('broker.example.com') as c:
+        ch = c.channel()
+        ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
+
+Producer publishing to ``test_exchange`` exchange with publisher confirms 
enabled and using virtual_host ``test_vhost``:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection(
+        'broker.example.com', exchange='test_exchange',
+        confirm_publish=True, virtual_host='test_vhost'
+    ) as c:
+        ch = c.channel()
+        ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
+
+Consumer with acknowledgments enabled:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection('broker.example.com') as c:
+        ch = c.channel()
+        def on_message(message):
+            print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
+            ch.basic_ack(message.delivery_tag)
+        ch.basic_consume(queue='test', callback=on_message)
+        while True:
+            c.drain_events()
+
+
+Consumer with acknowledgments disabled:
+
+.. code:: python
+
+    import amqp
+
+    with amqp.Connection('broker.example.com') as c:
+        ch = c.channel()
+        def on_message(message):
+            print('Received message (delivery tag: {}): 
{}'.format(message.delivery_tag, message.body))
+        ch.basic_consume(queue='test', callback=on_message, no_ack=True)
+        while True:
+            c.drain_events()
+
+Speedups
+========
+
+This library has **experimental** support of speedups. Speedups are 
implemented using Cython. To enable speedups, ``CELERY_ENABLE_SPEEDUPS`` 
environment variable must be set during building/installation.
+Currently speedups can be installed:
+
+1. using source package (using ``--no-binary`` switch):
+
+.. code:: shell
+
+    CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
+
+
+2. building directly source code:
+
+.. code:: shell
+
+    CELERY_ENABLE_SPEEDUPS=true python setup.py install
+
+Further
+=======
+
+- Differences between AMQP 0.8 and 0.9.1
+
+    http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
+
+- AMQP 0.9.1 Quick Reference
+
+    http://www.rabbitmq.com/amqp-0-9-1-quickref.html
+
+- RabbitMQ Extensions
+
+    http://www.rabbitmq.com/extensions.html
+
+- For more information about AMQP, visit
+
+    http://www.amqp.org
+
+- For other Python client libraries see:
+
+    http://www.rabbitmq.com/devtools.html#python-dev
+
+.. |build-status| image:: 
https://api.travis-ci.com/celery/py-amqp.png?branch=master
+    :alt: Build status
+    :target: https://travis-ci.com/celery/py-amqp
+
+.. |coverage| image:: 
https://codecov.io/github/celery/py-amqp/coverage.svg?branch=master
+    :target: https://codecov.io/github/celery/py-amqp?branch=master
+
+.. |license| image:: https://img.shields.io/pypi/l/amqp.svg
+    :alt: BSD License
+    :target: https://opensource.org/licenses/BSD-3-Clause
+
+.. |wheel| image:: https://img.shields.io/pypi/wheel/amqp.svg
+    :alt: Python AMQP can be installed via wheel
+    :target: https://pypi.org/project/amqp/
+
+.. |pyversion| image:: https://img.shields.io/pypi/pyversions/amqp.svg
+    :alt: Supported Python versions.
+    :target: https://pypi.org/project/amqp/
+
+.. |pyimp| image:: https://img.shields.io/pypi/implementation/amqp.svg
+    :alt: Support Python implementations.
+    :target: https://pypi.org/project/amqp/
+    
+py-amqp as part of the Tidelift Subscription
+============================================
+
+The maintainers of py-amqp and thousands of other packages are working with 
Tidelift to deliver commercial support and maintenance for the open source 
dependencies you use to build your applications. Save time, reduce risk, and 
improve code health, while paying the maintainers of the exact dependencies you 
use. [Learn 
more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
+
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/amqp.egg-info/SOURCES.txt 
new/amqp-5.0.8/amqp.egg-info/SOURCES.txt
--- old/amqp-5.0.6/amqp.egg-info/SOURCES.txt    2021-04-01 08:11:47.000000000 
+0200
+++ new/amqp-5.0.8/amqp.egg-info/SOURCES.txt    2021-12-19 06:06:23.000000000 
+0100
@@ -56,11 +56,13 @@
 requirements/test-ci.txt
 requirements/test.txt
 t/__init__.py
+t/mocks.py
 t/integration/__init__.py
 t/integration/conftest.py
 t/integration/test_integration.py
 t/integration/test_rmq.py
 t/unit/__init__.py
+t/unit/conftest.py
 t/unit/test_abstract_channel.py
 t/unit/test_basic_message.py
 t/unit/test_channel.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/docs/includes/introduction.txt 
new/amqp-5.0.8/docs/includes/introduction.txt
--- old/amqp-5.0.6/docs/includes/introduction.txt       2021-04-01 
06:42:21.000000000 +0200
+++ new/amqp-5.0.8/docs/includes/introduction.txt       2021-12-19 
06:03:07.000000000 +0100
@@ -1,4 +1,4 @@
-:Version: 5.0.6
+:Version: 5.0.8
 :Web: https://amqp.readthedocs.io/
 :Download: https://pypi.org/project/amqp/
 :Source: http://github.com/celery/py-amqp/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/requirements/pkgutils.txt 
new/amqp-5.0.8/requirements/pkgutils.txt
--- old/amqp-5.0.6/requirements/pkgutils.txt    2021-01-28 17:38:43.000000000 
+0100
+++ new/amqp-5.0.8/requirements/pkgutils.txt    2021-12-19 05:49:08.000000000 
+0100
@@ -1,6 +1,6 @@
 setuptools>=20.6.7
 wheel>=0.29.0
-flake8==3.8.3
+flake8>=3.8.3
 tox>=2.3.1
 sphinx2rst>=1.0
 bumpversion
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/requirements/test-ci.txt 
new/amqp-5.0.8/requirements/test-ci.txt
--- old/amqp-5.0.6/requirements/test-ci.txt     2021-04-01 06:06:52.000000000 
+0200
+++ new/amqp-5.0.8/requirements/test-ci.txt     2021-12-12 06:39:40.000000000 
+0100
@@ -1,4 +1,3 @@
 pytest-cov
 codecov
-pytest-travis-fold
 pytest-xdist
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/requirements/test.txt 
new/amqp-5.0.8/requirements/test.txt
--- old/amqp-5.0.6/requirements/test.txt        2020-06-01 07:25:14.000000000 
+0200
+++ new/amqp-5.0.8/requirements/test.txt        2021-12-19 05:48:27.000000000 
+0100
@@ -1,4 +1,3 @@
-case>=1.3.1
-pytest>=3.0,<=5.3.5
+pytest>=6.2.5,<=7.0.0
 pytest-sugar>=0.9.1
 pytest-rerunfailures>=6.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/setup.py new/amqp-5.0.8/setup.py
--- old/amqp-5.0.6/setup.py     2021-04-01 08:02:15.000000000 +0200
+++ new/amqp-5.0.8/setup.py     2021-12-19 05:50:47.000000000 +0100
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import re
 import sys
@@ -20,6 +20,8 @@
     Programming Language :: Python :: 3.6
     Programming Language :: Python :: 3.7
     Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
+    Programming Language :: Python :: 3.10
     Programming Language :: Python :: Implementation :: CPython
     Programming Language :: Python :: Implementation :: PyPy
     License :: OSI Approved :: BSD License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/t/integration/test_integration.py 
new/amqp-5.0.8/t/integration/test_integration.py
--- old/amqp-5.0.6/t/integration/test_integration.py    2021-01-28 
17:38:45.000000000 +0100
+++ new/amqp-5.0.8/t/integration/test_integration.py    2021-11-18 
09:18:39.000000000 +0100
@@ -114,7 +114,7 @@
 
 class DataComparator:
     # Comparator used for asserting serialized data. It can be used
-    # in cases when direct comparision of bytestream cannot be used
+    # in cases when direct comparison of bytestream cannot be used
     # (mainly cases of Table type where order of items can vary)
     def __init__(self, argsig, items):
         self.argsig = argsig
@@ -367,7 +367,7 @@
     @patch('amqp.Connection._on_blocked')
     def test_connecion_ignore_methods_during_close(self, on_blocked_mock):
         # Test checking that py-amqp will discard any received methods
-        # except Close and Close-OK after sending Connecion.Close method
+        # except Close and Close-OK after sending Connection.Close method
         # to server.
         frame_writer_cls_mock = Mock()
         frame_writer_mock = frame_writer_cls_mock()
@@ -601,7 +601,7 @@
                 callback_mock.assert_called_once()
 
     def test_basic_publish(self):
-        # Test verifing publishing message.
+        # Test verifying publishing message.
         frame_writer_cls_mock = Mock()
         conn = Connection(frame_writer=frame_writer_cls_mock)
         with patch.object(conn, 'Transport') as transport_mock:
@@ -621,7 +621,7 @@
             )
 
     def test_consume_no_consumer_tag(self):
-        # Test verifing starting consuming without specified consumer_tag
+        # Test verifying starting consuming without specified consumer_tag
         callback_mock = Mock()
         frame_writer_cls_mock = Mock()
         conn = Connection(frame_writer=frame_writer_cls_mock)
@@ -652,7 +652,7 @@
             assert ret == 'amq.ctag-PCmzXGkhCw_v0Zq7jXyvkg'
 
     def test_consume_with_consumer_tag(self):
-        # Test verifing starting consuming with specified consumer_tag
+        # Test verifying starting consuming with specified consumer_tag
         callback_mock = Mock()
         frame_writer_cls_mock = Mock()
         conn = Connection(frame_writer=frame_writer_cls_mock)
@@ -745,7 +745,7 @@
             assert excinfo.value.method_sig == spec.Exchange.Declare
             # Client is sending to broker:
             # 1. Exchange Declare
-            # 2. Connection.CloseOk as reply to received Connecton.Close
+            # 2. Connection.CloseOk as reply to received Connection.Close
             frame_writer_calls = [
                 call(
                     1, 1, spec.Queue.Declare,
@@ -1024,7 +1024,7 @@
             assert excinfo.value.method_sig == spec.Exchange.Declare
             # Client is sending to broker:
             # 1. Exchange Declare
-            # 2. Connection.CloseOk as reply to received Connecton.Close
+            # 2. Connection.CloseOk as reply to received Connection.Close
             frame_writer_calls = [
                 call(
                     1, 1, spec.Exchange.Declare,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/t/mocks.py new/amqp-5.0.8/t/mocks.py
--- old/amqp-5.0.6/t/mocks.py   1970-01-01 01:00:00.000000000 +0100
+++ new/amqp-5.0.8/t/mocks.py   2021-11-18 09:18:39.000000000 +0100
@@ -0,0 +1,24 @@
+from unittest.mock import Mock
+
+class _ContextMock(Mock):
+    """Dummy class implementing __enter__ and __exit__
+    as the :keyword:`with` statement requires these to be implemented
+    in the class, not just the instance."""
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, *exc_info):
+        pass
+
+
+def ContextMock(*args, **kwargs):
+    """Mock that mocks :keyword:`with` statement contexts."""
+    obj = _ContextMock(*args, **kwargs)
+    obj.attach_mock(_ContextMock(), '__enter__')
+    obj.attach_mock(_ContextMock(), '__exit__')
+    obj.__enter__.return_value = obj
+    # if __exit__ return a value the exception is ignored,
+    # so it must return None here.
+    obj.__exit__.return_value = None
+    return obj
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/t/unit/conftest.py 
new/amqp-5.0.8/t/unit/conftest.py
--- old/amqp-5.0.6/t/unit/conftest.py   1970-01-01 01:00:00.000000000 +0100
+++ new/amqp-5.0.8/t/unit/conftest.py   2021-11-18 09:18:39.000000000 +0100
@@ -0,0 +1,54 @@
+from unittest.mock import MagicMock
+import pytest
+
+sentinel = object()
+
+class _patching:
+
+    def __init__(self, monkeypatch, request):
+        self.monkeypatch = monkeypatch
+        self.request = request
+
+    def __getattr__(self, name):
+        return getattr(self.monkeypatch, name)
+
+    def __call__(self, path, value=sentinel, name=None,
+                 new=MagicMock, **kwargs):
+        value = self._value_or_mock(value, new, name, path, **kwargs)
+        self.monkeypatch.setattr(path, value)
+        return value
+
+    def _value_or_mock(self, value, new, name, path, **kwargs):
+        if value is sentinel:
+            value = new(name=name or path.rpartition('.')[2])
+        for k, v in kwargs.items():
+            setattr(value, k, v)
+        return value
+
+    def setattr(self, target, name=sentinel, value=sentinel, **kwargs):
+        # alias to __call__ with the interface of pytest.monkeypatch.setattr
+        if value is sentinel:
+            value, name = name, None
+        return self(target, value, name=name)
+
+    def setitem(self, dic, name, value=sentinel, new=MagicMock, **kwargs):
+        # same as pytest.monkeypatch.setattr but default value is MagicMock
+        value = self._value_or_mock(value, new, name, dic, **kwargs)
+        self.monkeypatch.setitem(dic, name, value)
+        return value
+
+
+@pytest.fixture
+def patching(monkeypatch, request):
+    """Monkeypath.setattr shortcut.
+    Example:
+        .. code-block:: python
+        def test_foo(patching):
+            # execv value here will be mock.MagicMock by default.
+            execv = patching('os.execv')
+            patching('sys.platform', 'darwin')  # set concrete value
+            patching.setenv('DJANGO_SETTINGS_MODULE', 'x.settings')
+            # val will be of type mock.MagicMock by default
+            val = patching.setitem('path.to.dict', 'KEY')
+    """
+    return _patching(monkeypatch, request)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/t/unit/test_channel.py 
new/amqp-5.0.8/t/unit/test_channel.py
--- old/amqp-5.0.6/t/unit/test_channel.py       2021-01-28 17:38:47.000000000 
+0100
+++ new/amqp-5.0.8/t/unit/test_channel.py       2021-11-18 09:18:39.000000000 
+0100
@@ -3,7 +3,6 @@
 from unittest.mock import ANY, MagicMock, Mock, patch
 
 import pytest
-from case import ContextMock
 from vine import promise
 
 from amqp import spec
@@ -13,6 +12,7 @@
                              RecoverableConnectionError)
 from amqp.serialization import dumps
 
+from t.mocks import ContextMock
 
 class test_Channel:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/t/unit/test_connection.py 
new/amqp-5.0.8/t/unit/test_connection.py
--- old/amqp-5.0.6/t/unit/test_connection.py    2021-01-28 17:38:47.000000000 
+0100
+++ new/amqp-5.0.8/t/unit/test_connection.py    2021-12-17 04:55:58.000000000 
+0100
@@ -1,10 +1,10 @@
 import re
 import socket
 import warnings
+from array import array
 from unittest.mock import Mock, call, patch
 
 import pytest
-from case import ContextMock
 
 from amqp import Connection, spec
 from amqp.connection import SSLError
@@ -13,6 +13,8 @@
 from amqp.sasl import AMQPLAIN, EXTERNAL, GSSAPI, PLAIN, SASL
 from amqp.transport import TCPTransport
 
+from t.mocks import ContextMock
+
 
 class test_Connection:
 
@@ -322,10 +324,17 @@
                 channel.collect.assert_called_with()
         assert self.conn._transport is None
 
-    def test_collect__channel_raises_socket_error(self):
-        self.conn.channels = self.conn.channels = {1: Mock(name='c1')}
-        self.conn.channels[1].collect.side_effect = socket.error()
+    def test_collect__transport_socket_raises_os_error(self):
+        self.conn.transport = TCPTransport('localhost:5672')
+        sock = self.conn.transport.sock = Mock(name='sock')
+        channel = Mock(name='c1')
+        self.conn.channels = {1: channel}
+        sock.shutdown.side_effect = OSError
         self.conn.collect()
+        channel.collect.assert_called_with()
+        sock.close.assert_called_with()
+        assert self.conn._transport is None
+        assert self.conn.channels is None
 
     def test_collect_no_transport(self):
         self.conn = Connection()
@@ -339,8 +348,11 @@
         self.conn.collect()
         self.conn.collect()
 
+    def test_get_free_channel_id(self):
+        assert self.conn._get_free_channel_id() == 1
+
     def test_get_free_channel_id__raises_IndexError(self):
-        self.conn._avail_channel_ids = []
+        self.conn._used_channel_ids = array('H', range(1, 
self.conn.channel_max))
         with pytest.raises(ResourceError):
             self.conn._get_free_channel_id()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-5.0.6/t/unit/test_transport.py 
new/amqp-5.0.8/t/unit/test_transport.py
--- old/amqp-5.0.6/t/unit/test_transport.py     2021-02-25 13:35:44.000000000 
+0100
+++ new/amqp-5.0.8/t/unit/test_transport.py     2021-12-17 04:55:58.000000000 
+0100
@@ -282,6 +282,13 @@
         self.t.close()
         assert self.t.sock is None and self.t.connected is False
 
+    def test_close_os_error(self):
+        sock = self.t.sock = Mock()
+        sock.shutdown.side_effect = OSError
+        self.t.close()
+        sock.close.assert_called_with()
+        assert self.t.sock is None and self.t.connected is False
+
     def test_read_frame__timeout(self):
         self.t._read = Mock()
         self.t._read.side_effect = socket.timeout()
@@ -580,6 +587,16 @@
         self.t.connect()
         assert self.t.connected and self.t.sock is sock_obj
 
+    def test_close__close_error(self):
+        # sock.close() can raise an error if the fd is invalid
+        # make sure the socket is properly deallocated
+        sock = self.t.sock = Mock()
+        sock.unwrap.return_value = sock
+        sock.close.side_effect = OSError
+        self.t.close()
+        sock.close.assert_called_with()
+        assert self.t.sock is None and self.t.connected is False
+
 
 class test_SSLTransport:
     class Transport(transport.SSLTransport):
@@ -719,7 +736,7 @@
             )
             assert context.verify_mode == sentinel.CERT_REQS
 
-        # testing context creation inside _wrap_socket_sni() with parameter 
+        # testing context creation inside _wrap_socket_sni() with parameter
         # cert_reqs == ssl.CERT_NONE. Previously raised ValueError because
         # code path attempted to set context.verify_mode=ssl.CERT_NONE before
         # setting context.check_hostname = False which raised a ValueError
@@ -740,7 +757,7 @@
                 )
                 mock_load_default_certs.assert_not_called()
                 mock_wrap_socket.assert_called_once()
-        
+
         with patch('ssl.SSLContext.wrap_socket') as mock_wrap_socket:
             with patch('ssl.SSLContext.load_default_certs') as 
mock_load_default_certs:
                 sock = Mock()
@@ -828,6 +845,14 @@
         self.t._shutdown_transport()
         assert self.t.sock is sock.unwrap()
 
+    def test_close__unwrap_error(self):
+        # sock.unwrap() can raise an error if the was a connection failure
+        # make sure the socket is properly closed and deallocated
+        sock = self.t.sock = Mock()
+        sock.unwrap.side_effect = OSError
+        self.t.close()
+        assert self.t.sock is None
+
     def test_read_EOF(self):
         self.t.sock = Mock(name='SSLSocket')
         self.t.connected = True

Reply via email to