#
#
+# Exit code used by Popen.terminate()
TERMINATE = 0x10000
WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False))
WINSERVICE = sys.executable.lower().endswith("pythonservice.exe")
if self.returncode is None:
try:
_winapi.TerminateProcess(int(self._handle), TERMINATE)
- except OSError:
- if self.wait(timeout=1.0) is None:
+ except PermissionError:
+ # ERROR_ACCESS_DENIED (winerror 5) is received when the
+ # process already died.
+ code = _winapi.GetExitCodeProcess(int(self._handle))
+ if code == _winapi.STILL_ACTIVE:
raise
+ self.returncode = code
+ else:
+ self.returncode = -signal.SIGTERM
kill = terminate
def test_terminate(self):
exitcode = self._kill_process(multiprocessing.Process.terminate)
- if os.name != 'nt':
- self.assertEqual(exitcode, -signal.SIGTERM)
+ self.assertEqual(exitcode, -signal.SIGTERM)
def test_kill(self):
exitcode = self._kill_process(multiprocessing.Process.kill)
if os.name != 'nt':
self.assertEqual(exitcode, -signal.SIGKILL)
+ else:
+ self.assertEqual(exitcode, -signal.SIGTERM)
def test_cpu_count(self):
try:
--- /dev/null
+On Windows, multiprocessing ``Popen.terminate()`` now catchs
+:exc:`PermissionError` and get the process exit code. If the process is
+still running, raise again the :exc:`PermissionError`. Otherwise, the
+process terminated as expected: store its exit code. Patch by Victor
+Stinner.