[Python-checkins] cpython (3.4): asyncio: BaseSubprocessTransport.close() doesn't try to kill the process if it
victor.stinner
python-checkins at python.org
Tue Feb 10 14:51:17 CET 2015
https://hg.python.org/cpython/rev/645f3d750be1
changeset: 94579:645f3d750be1
branch: 3.4
parent: 94577:2a06379f6562
user: Victor Stinner <victor.stinner at gmail.com>
date: Tue Feb 10 14:49:32 2015 +0100
summary:
asyncio: BaseSubprocessTransport.close() doesn't try to kill the process if it
already finished
files:
Lib/asyncio/base_subprocess.py | 7 +-
Lib/test/test_asyncio/test_subprocess.py | 55 ++++++++++++
2 files changed, 61 insertions(+), 1 deletions(-)
diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py
--- a/Lib/asyncio/base_subprocess.py
+++ b/Lib/asyncio/base_subprocess.py
@@ -93,7 +93,12 @@
continue
proto.pipe.close()
- if self._proc is not None and self._returncode is None:
+ if (self._proc is not None
+ # the child process finished?
+ and self._returncode is None
+ # the child process finished but the transport was not notified yet?
+ and self._proc.poll() is None
+ ):
if self._loop.get_debug():
logger.warning('Close running child process: kill %r', self)
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -349,6 +349,61 @@
self.loop.run_until_complete(cancel_make_transport())
test_utils.run_briefly(self.loop)
+ def test_close_kill_running(self):
+ @asyncio.coroutine
+ def kill_running():
+ create = self.loop.subprocess_exec(asyncio.SubprocessProtocol,
+ *PROGRAM_BLOCKED)
+ transport, protocol = yield from create
+ proc = transport.get_extra_info('subprocess')
+ proc.kill = mock.Mock()
+ returncode = transport.get_returncode()
+ transport.close()
+ return (returncode, proc.kill.called)
+
+ # Ignore "Close running child process: kill ..." log
+ with test_utils.disable_logger():
+ returncode, killed = self.loop.run_until_complete(kill_running())
+ self.assertIsNone(returncode)
+
+ # transport.close() must kill the process if it is still running
+ self.assertTrue(killed)
+ test_utils.run_briefly(self.loop)
+
+ def test_close_dont_kill_finished(self):
+ @asyncio.coroutine
+ def kill_running():
+ create = self.loop.subprocess_exec(asyncio.SubprocessProtocol,
+ *PROGRAM_BLOCKED)
+ transport, protocol = yield from create
+ proc = transport.get_extra_info('subprocess')
+
+ # kill the process (but asyncio is not notified immediatly)
+ proc.kill()
+ proc.wait()
+
+ proc.kill = mock.Mock()
+ proc_returncode = proc.poll()
+ transport_returncode = transport.get_returncode()
+ transport.close()
+ return (proc_returncode, transport_returncode, proc.kill.called)
+
+ # Ignore "Unknown child process pid ..." log of SafeChildWatcher,
+ # emitted because the test already consumes the exit status:
+ # proc.wait()
+ with test_utils.disable_logger():
+ result = self.loop.run_until_complete(kill_running())
+ test_utils.run_briefly(self.loop)
+
+ proc_returncode, transport_return_code, killed = result
+
+ self.assertIsNotNone(proc_returncode)
+ self.assertIsNone(transport_return_code)
+
+ # transport.close() must not kill the process if it finished, even if
+ # the transport was not notified yet
+ self.assertFalse(killed)
+
if sys.platform != 'win32':
# Unix
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list