Added kill, terminate and send_signal to subprocess.Popen
The bits and pieces for the Windows side were already in place. The POSIX side is trivial (as usual) and uses os.kill().
This commit is contained in:
parent
c873550737
commit
e74c8f2879
|
@ -208,6 +208,29 @@ Instances of the :class:`Popen` class have the following methods:
|
||||||
size is large or unlimited.
|
size is large or unlimited.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: Popen.send_signal(signal)
|
||||||
|
|
||||||
|
Sends the signal *signal* to the child.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
On Windows only SIGTERM is supported so far. It's an alias for
|
||||||
|
*terminate*.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: Popen.terminate()
|
||||||
|
|
||||||
|
Stop the child. On Posix OSs the method sends SIGTERM to the
|
||||||
|
child. On Windows the Win32 API function TerminateProcess is called
|
||||||
|
to stop the child.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: Popen.kill()
|
||||||
|
|
||||||
|
Kills the child. On Posix OSs the function sends SIGKILL to the child.
|
||||||
|
On Windows *kill* is an alias for *terminate*.
|
||||||
|
|
||||||
|
|
||||||
The following attributes are also available:
|
The following attributes are also available:
|
||||||
|
|
||||||
.. attribute:: Popen.stdin
|
.. attribute:: Popen.stdin
|
||||||
|
|
|
@ -357,6 +357,7 @@ import os
|
||||||
import types
|
import types
|
||||||
import traceback
|
import traceback
|
||||||
import gc
|
import gc
|
||||||
|
import signal
|
||||||
|
|
||||||
# Exception classes used by this module.
|
# Exception classes used by this module.
|
||||||
class CalledProcessError(Exception):
|
class CalledProcessError(Exception):
|
||||||
|
@ -384,6 +385,7 @@ if mswindows:
|
||||||
from win32process import CreateProcess, STARTUPINFO, \
|
from win32process import CreateProcess, STARTUPINFO, \
|
||||||
GetExitCodeProcess, STARTF_USESTDHANDLES, \
|
GetExitCodeProcess, STARTF_USESTDHANDLES, \
|
||||||
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
|
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
|
||||||
|
from win32process import TerminateProcess
|
||||||
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
|
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
|
||||||
else:
|
else:
|
||||||
from _subprocess import *
|
from _subprocess import *
|
||||||
|
@ -906,6 +908,21 @@ class Popen(object):
|
||||||
self.wait()
|
self.wait()
|
||||||
return (stdout, stderr)
|
return (stdout, stderr)
|
||||||
|
|
||||||
|
def send_signal(self, sig):
|
||||||
|
"""Send a signal to the process
|
||||||
|
"""
|
||||||
|
if sig == signal.SIGTERM:
|
||||||
|
self.terminate()
|
||||||
|
else:
|
||||||
|
raise ValueError("Only SIGTERM is supported on Windows")
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
"""Terminates the process
|
||||||
|
"""
|
||||||
|
TerminateProcess(self._handle, 1)
|
||||||
|
|
||||||
|
kill = terminate
|
||||||
|
|
||||||
else:
|
else:
|
||||||
#
|
#
|
||||||
# POSIX methods
|
# POSIX methods
|
||||||
|
@ -1184,6 +1201,21 @@ class Popen(object):
|
||||||
self.wait()
|
self.wait()
|
||||||
return (stdout, stderr)
|
return (stdout, stderr)
|
||||||
|
|
||||||
|
def send_signal(self, sig):
|
||||||
|
"""Send a signal to the process
|
||||||
|
"""
|
||||||
|
os.kill(self.pid, sig)
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
"""Terminate the process with SIGTERM
|
||||||
|
"""
|
||||||
|
self.send_signal(signal.SIGTERM)
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
"""Kill the process with SIGKILL
|
||||||
|
"""
|
||||||
|
self.send_signal(signal.SIGKILL)
|
||||||
|
|
||||||
|
|
||||||
def _demo_posix():
|
def _demo_posix():
|
||||||
#
|
#
|
||||||
|
|
|
@ -584,6 +584,29 @@ class ProcessTestCase(unittest.TestCase):
|
||||||
os.remove(fname)
|
os.remove(fname)
|
||||||
self.assertEqual(rc, 47)
|
self.assertEqual(rc, 47)
|
||||||
|
|
||||||
|
def test_send_signal(self):
|
||||||
|
p = subprocess.Popen([sys.executable,
|
||||||
|
"-c", "input()"])
|
||||||
|
|
||||||
|
self.assert_(p.poll() is None, p.poll())
|
||||||
|
p.send_signal(signal.SIGINT)
|
||||||
|
self.assertNotEqual(p.wait(), 0)
|
||||||
|
|
||||||
|
def test_kill(self):
|
||||||
|
p = subprocess.Popen([sys.executable,
|
||||||
|
"-c", "input()"])
|
||||||
|
|
||||||
|
self.assert_(p.poll() is None, p.poll())
|
||||||
|
p.kill()
|
||||||
|
self.assertEqual(p.wait(), -signal.SIGKILL)
|
||||||
|
|
||||||
|
def test_terminate(self):
|
||||||
|
p = subprocess.Popen([sys.executable,
|
||||||
|
"-c", "input()"])
|
||||||
|
|
||||||
|
self.assert_(p.poll() is None, p.poll())
|
||||||
|
p.terminate()
|
||||||
|
self.assertEqual(p.wait(), -signal.SIGTERM)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Windows tests
|
# Windows tests
|
||||||
|
@ -655,6 +678,29 @@ class ProcessTestCase(unittest.TestCase):
|
||||||
' -c "import sys; sys.exit(47)"')
|
' -c "import sys; sys.exit(47)"')
|
||||||
self.assertEqual(rc, 47)
|
self.assertEqual(rc, 47)
|
||||||
|
|
||||||
|
def test_send_signal(self):
|
||||||
|
p = subprocess.Popen([sys.executable,
|
||||||
|
"-c", "input()"])
|
||||||
|
|
||||||
|
self.assert_(p.poll() is None, p.poll())
|
||||||
|
p.send_signal(signal.SIGTERM)
|
||||||
|
self.assertNotEqual(p.wait(), 0)
|
||||||
|
|
||||||
|
def test_kill(self):
|
||||||
|
p = subprocess.Popen([sys.executable,
|
||||||
|
"-c", "input()"])
|
||||||
|
|
||||||
|
self.assert_(p.poll() is None, p.poll())
|
||||||
|
p.kill()
|
||||||
|
self.assertNotEqual(p.wait(), 0)
|
||||||
|
|
||||||
|
def test_terminate(self):
|
||||||
|
p = subprocess.Popen([sys.executable,
|
||||||
|
"-c", "input()"])
|
||||||
|
|
||||||
|
self.assert_(p.poll() is None, p.poll())
|
||||||
|
p.terminate()
|
||||||
|
self.assertNotEqual(p.wait(), 0)
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(ProcessTestCase)
|
test_support.run_unittest(ProcessTestCase)
|
||||||
|
|
|
@ -18,6 +18,8 @@ Core and builtins
|
||||||
Extensions Modules
|
Extensions Modules
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
- Added kill, terminate and send_signal(sig) to subprocess.Popen.
|
||||||
|
|
||||||
- Added phase(z) -> phi, polar(z) -> r, phi and rect(r, phi) -> z to the cmath
|
- Added phase(z) -> phi, polar(z) -> r, phi and rect(r, phi) -> z to the cmath
|
||||||
module.
|
module.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue