Fix 'NoneType' object has no attribute 'can_read' (#1107)

The root cause of the issue is that the connection
can be erased during an execution of self._receive_one(c).
So c.connection should be checked before every iteration,
not only before the first one.
This commit is contained in:
Aliaksei Urbanski 2019-10-23 21:27:47 +03:00 committed by Asif Saif Uddin
parent 977fe3d4f6
commit ef54bf06f7
2 changed files with 14 additions and 3 deletions

View File

@ -684,9 +684,8 @@ class Channel(virtual.Channel):
ret.append(self._receive_one(c))
except Empty:
pass
if c.connection is not None:
while c.connection.can_read(timeout=0):
ret.append(self._receive_one(c))
while c.connection is not None and c.connection.can_read(timeout=0):
ret.append(self._receive_one(c))
return any(ret)
def _receive_one(self, c):

View File

@ -807,6 +807,18 @@ class TestRedisChannel(unittest.TestCase):
assert self.channel._receive_one(self.channel.subclient) is None
def test_receive_connection_has_gone(self):
def _receive_one(c):
c.connection = None
_receive_one.called = True
return True
_receive_one.called = False
self.channel._receive_one = _receive_one
assert self.channel._receive()
assert _receive_one.called
def test_brpop_read_raises(self):
c = self.channel.client = Mock()
c.parse_response.side_effect = KeyError('foo')