Repository: celery/kombu

Issue:
Test failure with Python 3.6.0
The failures are not present in 3.5.0:

```
=================================== FAILURES ===================================
___________________________ test_Consumer.test_purge ___________________________

self = <t.unit.test_messaging.test_Consumer object at 0xf263c08c>

    def test_purge(self):
        channel = self.connection.channel()
        b1 = Queue('qname1', self.exchange, 'rkey')
        b2 = Queue('qname2', self.exchange, 'rkey')
        b3 = Queue('qname3', self.exchange, 'rkey')
        b4 = Queue('qname4', self.exchange, 'rkey')
>       consumer = Consumer(channel, [b1, b2, b3, b4], auto_declare=True)

t/unit/test_messaging.py:498: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
kombu/messaging.py:386: in __init__
    self.revive(self.channel)
kombu/messaging.py:407: in revive
    self.declare()
kombu/messaging.py:420: in declare
    queue.declare()
kombu/entity.py:604: in declare
    self._create_exchange(nowait=nowait, channel=channel)
kombu/entity.py:611: in _create_exchange
    self.exchange.declare(nowait=nowait, channel=channel)
kombu/entity.py:182: in declare
    return (channel or self.channel).exchange_declare(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <unbound Exchange foo(direct)>

    @property
    def channel(self):
        """Current channel if the object is bound."""
        channel = self._channel
        if channel is None:
            raise NotBoundError(
                "Can't call method on {0} not bound to a channel".format(
>                   type(self).__name__))
E           kombu.exceptions.NotBoundError: Can't call method on Exchange not bound to a channel

kombu/abstract.py:119: NotBoundError
______________________ test_Consumer.test_multiple_queues ______________________

self = <t.unit.test_messaging.test_Consumer object at 0xf247f88c>

    def test_multiple_queues(self):
        channel = self.connection.channel()
        b1 = Queue('qname1', self.exchange, 'rkey')
        b2 = Queue('qname2', self.exchange, 'rkey')
        b3 = Queue('qname3', self.exchange, 'rkey')
        b4 = Queue('qname4', self.exchange, 'rkey')
>       consumer = Consumer(channel, [b1, b2, b3, b4])

t/unit/test_messaging.py:508: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
kombu/messaging.py:386: in __init__
    self.revive(self.channel)
kombu/messaging.py:407: in revive
    self.declare()
kombu/messaging.py:420: in declare
    queue.declare()
kombu/entity.py:604: in declare
    self._create_exchange(nowait=nowait, channel=channel)
kombu/entity.py:611: in _create_exchange
    self.exchange.declare(nowait=nowait, channel=channel)
kombu/entity.py:182: in declare
    return (channel or self.channel).exchange_declare(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <unbound Exchange foo(direct)>

    @property
    def channel(self):
        """Current channel if the object is bound."""
        channel = self._channel
        if channel is None:
            raise NotBoundError(
                "Can't call method on {0} not bound to a channel".format(
>                   type(self).__name__))
E           kombu.exceptions.NotBoundError: Can't call method on Exchange not bound to a channel

kombu/abstract.py:119: NotBoundError
============== 2 failed, 834 passed, 303 skipped in 11.37 seconds ==============
```


Discussion:

Resolving patch:
diff --git a/kombu/messaging.py b/kombu/messaging.py
--- a/kombu/messaging.py
+++ b/kombu/messaging.py
@@ -397,7 +397,8 @@ def revive(self, channel):
         """Revive consumer after connection loss."""
         self._active_tags.clear()
         channel = self.channel = maybe_channel(channel)
-        for qname, queue in items(self._queues):
+        # modify dict size while iterating over it is not allowed
+        for qname, queue in list(items(self._queues)):
             # name may have changed after declare
             self._queues.pop(qname, None)
             queue = self._queues[queue.name] = queue(self.channel)


Test patch: