changeset: 101870:9512cfd53903 branch: 3.5 parent: 101867:62b949a179cb user: Yury Selivanov date: Sat Jun 11 11:19:47 2016 -0400 files: Lib/asyncio/selector_events.py Lib/test/test_asyncio/test_selector_events.py Misc/NEWS description: Issue #27223: aio: Fix _read_ready and _write_ready to respect _conn_lost. Patch by Łukasz Langa. diff -r 62b949a179cb -r 9512cfd53903 Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py Sat Jun 11 04:31:22 2016 -0400 +++ b/Lib/asyncio/selector_events.py Sat Jun 11 11:19:47 2016 -0400 @@ -569,6 +569,7 @@ self._loop.remove_reader(self._sock_fd) if not self._buffer: self._conn_lost += 1 + self._loop.remove_writer(self._sock_fd) self._loop.call_soon(self._call_connection_lost, None) # On Python 3.3 and older, objects with a destructor part of a reference @@ -662,6 +663,8 @@ logger.debug("%r resumes reading", self) def _read_ready(self): + if self._conn_lost: + return try: data = self._sock.recv(self.max_size) except (BlockingIOError, InterruptedError): @@ -721,6 +724,8 @@ def _write_ready(self): assert self._buffer, 'Data should not be empty' + if self._conn_lost: + return try: n = self._sock.send(self._buffer) except (BlockingIOError, InterruptedError): @@ -891,6 +896,8 @@ logger.debug("%r resumes reading", self) def _read_ready(self): + if self._conn_lost: + return if self._write_wants_read: self._write_wants_read = False self._write_ready() @@ -923,6 +930,8 @@ self.close() def _write_ready(self): + if self._conn_lost: + return if self._read_wants_write: self._read_wants_write = False self._read_ready() @@ -1000,6 +1009,8 @@ return sum(len(data) for data, _ in self._buffer) def _read_ready(self): + if self._conn_lost: + return try: data, addr = self._sock.recvfrom(self.max_size) except (BlockingIOError, InterruptedError): diff -r 62b949a179cb -r 9512cfd53903 Lib/test/test_asyncio/test_selector_events.py --- a/Lib/test/test_asyncio/test_selector_events.py Sat Jun 11 04:31:22 2016 -0400 +++ b/Lib/test/test_asyncio/test_selector_events.py Sat Jun 11 11:19:47 2016 -0400 @@ -1087,17 +1087,6 @@ err, 'Fatal write error on socket transport') - @mock.patch('asyncio.base_events.logger') - def test_write_ready_exception_and_close(self, m_log): - self.sock.send.side_effect = OSError() - remove_writer = self.loop.remove_writer = mock.Mock() - - transport = self.socket_transport() - transport.close() - transport._buffer.extend(b'data') - transport._write_ready() - remove_writer.assert_called_with(self.sock_fd) - def test_write_eof(self): tr = self.socket_transport() self.assertTrue(tr.can_write_eof()) @@ -1121,6 +1110,14 @@ self.sock.shutdown.assert_called_with(socket.SHUT_WR) tr.close() + @mock.patch('asyncio.base_events.logger') + def test_transport_close_remove_writer(self, m_log): + remove_writer = self.loop.remove_writer = mock.Mock() + + transport = self.socket_transport() + transport.close() + remove_writer.assert_called_with(self.sock_fd) + @unittest.skipIf(ssl is None, 'No ssl module') class SelectorSslTransportTests(test_utils.TestCase): @@ -1175,7 +1172,7 @@ self.sslsock.do_handshake.side_effect = exc with test_utils.disable_logger(): waiter = asyncio.Future(loop=self.loop) - transport = self.ssl_transport(waiter=waiter) + self.ssl_transport(waiter=waiter) self.assertTrue(waiter.done()) self.assertIs(exc, waiter.exception()) self.assertTrue(self.sslsock.close.called) @@ -1374,20 +1371,19 @@ def test_write_ready_send_closing(self): self.sslsock.send.return_value = 4 transport = self._make_one() + transport._buffer = list_to_buffer([b'data']) transport.close() - transport._buffer = list_to_buffer([b'data']) transport._write_ready() - self.assertFalse(self.loop.writers) self.protocol.connection_lost.assert_called_with(None) def test_write_ready_send_closing_empty_buffer(self): self.sslsock.send.return_value = 4 + call_soon = self.loop.call_soon = mock.Mock() transport = self._make_one() - transport.close() transport._buffer = list_to_buffer() + transport.close() transport._write_ready() - self.assertFalse(self.loop.writers) - self.protocol.connection_lost.assert_called_with(None) + call_soon.assert_called_with(transport._call_connection_lost, None) def test_write_ready_send_retry(self): transport = self._make_one() diff -r 62b949a179cb -r 9512cfd53903 Misc/NEWS --- a/Misc/NEWS Sat Jun 11 04:31:22 2016 -0400 +++ b/Misc/NEWS Sat Jun 11 11:19:47 2016 -0400 @@ -520,6 +520,10 @@ - Issue #27041: asyncio: Add loop.create_future method +- Issue #27223: asyncio: Fix _read_ready and _write_ready to respect + _conn_lost. + Patch by Łukasz Langa. + IDLE ---- @@ -709,7 +713,7 @@ Misc ---- -- Issue #17500, and https://github.com/python/pythondotorg/issues/945: Remove +- Issue #17500, and https://github.com/python/pythondotorg/issues/945: Remove unused and outdated icons.