From 5bb1afb3322ecf370cf328d40fb95eb0a3ddab7c Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 16 Nov 2015 12:43:21 -0500 Subject: [PATCH] asyncio: Add Transport.is_closing() See https://github.com/python/asyncio/pull/291 for details. --- Lib/asyncio/base_subprocess.py | 3 +++ Lib/asyncio/proactor_events.py | 3 +++ Lib/asyncio/selector_events.py | 3 +++ Lib/asyncio/sslproto.py | 3 +++ Lib/asyncio/streams.py | 2 +- Lib/asyncio/transports.py | 4 ++++ Lib/asyncio/unix_events.py | 6 ++++++ Lib/test/test_asyncio/test_proactor_events.py | 6 +++--- Lib/test/test_asyncio/test_selector_events.py | 6 +++--- Lib/test/test_asyncio/test_subprocess.py | 2 +- Lib/test/test_asyncio/test_unix_events.py | 12 ++++++------ 11 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index 6851cd2b88e..73425d9bbcc 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -87,6 +87,9 @@ class BaseSubprocessTransport(transports.SubprocessTransport): def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError + def is_closing(self): + return self._closed + def close(self): if self._closed: return diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index abe4c129c9b..9c514c8345d 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -65,6 +65,9 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, def _set_extra(self, sock): self._extra['pipe'] = sock + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 0060912219e..236f7b36a8d 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -556,6 +556,9 @@ class _SelectorTransport(transports._FlowControlMixin, def abort(self): self._force_close(None) + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 9e08b6f88bc..dde980b68f8 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -304,6 +304,9 @@ class _SSLProtocolTransport(transports._FlowControlMixin, """Get optional transport information.""" return self._ssl_protocol._get_extra_info(name, default) + def is_closing(self): + return self._closed + def close(self): """Close the transport. diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 64d10203d24..6b5e96aea2c 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -302,7 +302,7 @@ class StreamWriter: if exc is not None: raise exc if self._transport is not None: - if self._transport._closing: + if self._transport.is_closing(): # Yield to the event loop so connection_lost() may be # called. Without this, _drain_helper() would return # immediately, and code that calls diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 03099e3e541..9a6d9197d9a 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -19,6 +19,10 @@ class BaseTransport: """Get optional transport information.""" return self._extra.get(name, default) + def is_closing(self): + """Return True if the transport is closing or closed.""" + raise NotImplementedError + def close(self): """Close the transport. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index bf3b0844fda..f75e89f3175 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -364,6 +364,9 @@ class _UnixReadPipeTransport(transports.ReadTransport): def resume_reading(self): self._loop.add_reader(self._fileno, self._read_ready) + def is_closing(self): + return self._closing + def close(self): if not self._closing: self._close(None) @@ -548,6 +551,9 @@ class _UnixWritePipeTransport(transports._FlowControlMixin, self._loop.remove_reader(self._fileno) self._loop.call_soon(self._call_connection_lost, None) + def is_closing(self): + return self._closing + def close(self): if self._pipe is not None and not self._closing: # write_eof is all what we needed to close the write pipe diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index fcd9ab1e18f..5a0f0881e4c 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -204,7 +204,7 @@ class ProactorSocketTransportTests(test_utils.TestCase): tr.close() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._conn_lost, 1) self.protocol.connection_lost.reset_mock() @@ -298,7 +298,7 @@ class ProactorSocketTransportTests(test_utils.TestCase): self.loop, self.sock, self.protocol) self.assertTrue(tr.can_write_eof()) tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.loop._run_once() self.assertTrue(self.sock.close.called) tr.close() @@ -309,7 +309,7 @@ class ProactorSocketTransportTests(test_utils.TestCase): tr._loop._proactor.send.return_value = f tr.write(b'data') tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.sock.shutdown.called) tr._loop._proactor.send.assert_called_with(self.sock, b'data') f.set_result(4) diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index f0fcdd22ae6..135b5abf101 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -698,7 +698,7 @@ class SelectorTransportTests(test_utils.TestCase): tr = self.create_transport() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[7]) self.protocol.connection_lost(None) self.assertEqual(tr._conn_lost, 1) @@ -723,7 +723,7 @@ class SelectorTransportTests(test_utils.TestCase): self.loop.add_writer(7, mock.sentinel) tr._force_close(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._buffer, list_to_buffer()) self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) @@ -1436,7 +1436,7 @@ class SelectorSslTransportTests(test_utils.TestCase): tr = self._make_one() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[1]) self.assertEqual(tr._conn_lost, 1) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 38f0ceeb1f2..e90f17dda63 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -61,7 +61,7 @@ class SubprocessTransportTests(test_utils.TestCase): self.assertTrue(protocol.connection_lost.called) self.assertEqual(protocol.connection_lost.call_args[0], (None,)) - self.assertFalse(transport._closed) + self.assertFalse(transport.is_closing()) self.assertIsNone(transport._loop) self.assertIsNone(transport._proc) self.assertIsNone(transport._protocol) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index dc0835c527d..22dc6880360 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -440,7 +440,7 @@ class UnixReadPipeTransportTests(test_utils.TestCase): tr = self.read_pipe_transport() err = object() tr._close(err) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) @@ -598,7 +598,7 @@ class UnixWritePipeTransportTests(test_utils.TestCase): tr._read_ready() self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -658,7 +658,7 @@ class UnixWritePipeTransportTests(test_utils.TestCase): self.assertFalse(self.loop.writers) self.assertFalse(self.loop.readers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) m_logexc.assert_called_with( test_utils.MockPattern( 'Fatal write error on pipe transport' @@ -694,7 +694,7 @@ class UnixWritePipeTransportTests(test_utils.TestCase): self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -743,7 +743,7 @@ class UnixWritePipeTransportTests(test_utils.TestCase): def test_write_eof(self): tr = self.write_pipe_transport() tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -752,7 +752,7 @@ class UnixWritePipeTransportTests(test_utils.TestCase): tr = self.write_pipe_transport() tr._buffer = [b'data'] tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.protocol.connection_lost.called)