From 2335de7a2082f05c43977996533cee93384ff7a9 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 15 Nov 2013 16:51:48 -0800 Subject: asyncio: Replace connection_refused() with error_received(). --- Lib/asyncio/protocols.py | 12 ++++++---- Lib/asyncio/selector_events.py | 17 +++++--------- Lib/test/test_asyncio/test_base_events.py | 2 +- Lib/test/test_asyncio/test_events.py | 4 ++-- Lib/test/test_asyncio/test_selector_events.py | 33 +++++++++++++++++++-------- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/Lib/asyncio/protocols.py b/Lib/asyncio/protocols.py index d3a8685..eb94fb6 100644 --- a/Lib/asyncio/protocols.py +++ b/Lib/asyncio/protocols.py @@ -100,15 +100,18 @@ class DatagramProtocol(BaseProtocol): def datagram_received(self, data, addr): """Called when some datagram is received.""" - def connection_refused(self, exc): - """Connection is refused.""" + def error_received(self, exc): + """Called when a send or receive operation raises an OSError. + + (Other than BlockingIOError or InterruptedError.) + """ class SubprocessProtocol(BaseProtocol): """ABC representing a protocol for subprocess calls.""" def pipe_data_received(self, fd, data): - """Called when subprocess write a data into stdout/stderr pipes. + """Called when the subprocess writes data into stdout/stderr pipe. fd is int file dascriptor. data is bytes object. @@ -122,5 +125,4 @@ class SubprocessProtocol(BaseProtocol): """ def process_exited(self): - """Called when subprocess has exited. - """ + """Called when subprocess has exited.""" diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 3bad198..3efa4d2 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -771,6 +771,8 @@ class _SelectorDatagramTransport(_SelectorTransport): data, addr = self._sock.recvfrom(self.max_size) except (BlockingIOError, InterruptedError): pass + except OSError as exc: + self._protocol.error_received(exc) except Exception as exc: self._fatal_error(exc) else: @@ -800,9 +802,8 @@ class _SelectorDatagramTransport(_SelectorTransport): return except (BlockingIOError, InterruptedError): self._loop.add_writer(self._sock_fd, self._sendto_ready) - except ConnectionRefusedError as exc: - if self._address: - self._fatal_error(exc) + except OSError as exc: + self._protocol.error_received(exc) return except Exception as exc: self._fatal_error(exc) @@ -822,9 +823,8 @@ class _SelectorDatagramTransport(_SelectorTransport): except (BlockingIOError, InterruptedError): self._buffer.appendleft((data, addr)) # Try again later. break - except ConnectionRefusedError as exc: - if self._address: - self._fatal_error(exc) + except OSError as exc: + self._protocol.error_received(exc) return except Exception as exc: self._fatal_error(exc) @@ -835,8 +835,3 @@ class _SelectorDatagramTransport(_SelectorTransport): self._loop.remove_writer(self._sock_fd) if self._closing: self._call_connection_lost(None) - - def _force_close(self, exc): - if self._address and isinstance(exc, ConnectionRefusedError): - self._protocol.connection_refused(exc) - super()._force_close(exc) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 5178d54..ff537ab 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -284,7 +284,7 @@ class MyDatagramProto(protocols.DatagramProtocol): assert self.state == 'INITIALIZED', self.state self.nbytes += len(data) - def connection_refused(self, exc): + def error_received(self, exc): assert self.state == 'INITIALIZED', self.state def connection_lost(self, exc): diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 2338546..3a2dece 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -78,7 +78,7 @@ class MyDatagramProto(protocols.DatagramProtocol): assert self.state == 'INITIALIZED', self.state self.nbytes += len(data) - def connection_refused(self, exc): + def error_received(self, exc): assert self.state == 'INITIALIZED', self.state def connection_lost(self, exc): @@ -1557,7 +1557,7 @@ class ProtocolsAbsTests(unittest.TestCase): dp = protocols.DatagramProtocol() self.assertIsNone(dp.connection_made(f)) self.assertIsNone(dp.connection_lost(f)) - self.assertIsNone(dp.connection_refused(f)) + self.assertIsNone(dp.error_received(f)) self.assertIsNone(dp.datagram_received(f, f)) sp = protocols.SubprocessProtocol() diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 04a7d0c..4aef2fd 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -1329,12 +1329,23 @@ class SelectorDatagramTransportTests(unittest.TestCase): transport = _SelectorDatagramTransport( self.loop, self.sock, self.protocol) - err = self.sock.recvfrom.side_effect = OSError() + err = self.sock.recvfrom.side_effect = RuntimeError() transport._fatal_error = unittest.mock.Mock() transport._read_ready() transport._fatal_error.assert_called_with(err) + def test_read_ready_oserr(self): + transport = _SelectorDatagramTransport( + self.loop, self.sock, self.protocol) + + err = self.sock.recvfrom.side_effect = OSError() + transport._fatal_error = unittest.mock.Mock() + transport._read_ready() + + self.assertFalse(transport._fatal_error.called) + self.protocol.error_received.assert_called_with(err) + def test_sendto(self): data = b'data' transport = _SelectorDatagramTransport( @@ -1380,7 +1391,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): @unittest.mock.patch('asyncio.selector_events.logger') def test_sendto_exception(self, m_log): data = b'data' - err = self.sock.sendto.side_effect = OSError() + err = self.sock.sendto.side_effect = RuntimeError() transport = _SelectorDatagramTransport( self.loop, self.sock, self.protocol) @@ -1399,7 +1410,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): transport.sendto(data) m_log.warning.assert_called_with('socket.send() raised exception.') - def test_sendto_connection_refused(self): + def test_sendto_error_received(self): data = b'data' self.sock.sendto.side_effect = ConnectionRefusedError @@ -1412,7 +1423,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): self.assertEqual(transport._conn_lost, 0) self.assertFalse(transport._fatal_error.called) - def test_sendto_connection_refused_connected(self): + def test_sendto_error_received_connected(self): data = b'data' self.sock.send.side_effect = ConnectionRefusedError @@ -1422,7 +1433,8 @@ class SelectorDatagramTransportTests(unittest.TestCase): transport._fatal_error = unittest.mock.Mock() transport.sendto(data) - self.assertTrue(transport._fatal_error.called) + self.assertFalse(transport._fatal_error.called) + self.assertTrue(self.protocol.error_received.called) def test_sendto_str(self): transport = _SelectorDatagramTransport( @@ -1495,7 +1507,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): list(transport._buffer)) def test_sendto_ready_exception(self): - err = self.sock.sendto.side_effect = OSError() + err = self.sock.sendto.side_effect = RuntimeError() transport = _SelectorDatagramTransport( self.loop, self.sock, self.protocol) @@ -1505,7 +1517,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): transport._fatal_error.assert_called_with(err) - def test_sendto_ready_connection_refused(self): + def test_sendto_ready_error_received(self): self.sock.sendto.side_effect = ConnectionRefusedError transport = _SelectorDatagramTransport( @@ -1516,7 +1528,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): self.assertFalse(transport._fatal_error.called) - def test_sendto_ready_connection_refused_connection(self): + def test_sendto_ready_error_received_connection(self): self.sock.send.side_effect = ConnectionRefusedError transport = _SelectorDatagramTransport( @@ -1525,7 +1537,8 @@ class SelectorDatagramTransportTests(unittest.TestCase): transport._buffer.append((b'data', ())) transport._sendto_ready() - self.assertTrue(transport._fatal_error.called) + self.assertFalse(transport._fatal_error.called) + self.assertTrue(self.protocol.error_received.called) @unittest.mock.patch('asyncio.log.logger.exception') def test_fatal_error_connected(self, m_exc): @@ -1533,7 +1546,7 @@ class SelectorDatagramTransportTests(unittest.TestCase): self.loop, self.sock, self.protocol, ('0.0.0.0', 1)) err = ConnectionRefusedError() transport._fatal_error(err) - self.protocol.connection_refused.assert_called_with(err) + self.assertFalse(self.protocol.error_received.called) m_exc.assert_called_with('Fatal error for %s', transport) -- cgit v0.12