(original) (raw)
changeset: 71747:c2fd1ce1c6d4 parent: 71745:210d9a2dab09 parent: 71746:cc86f4ca5020 user: Ned Deily nad@acm.org date: Thu Aug 04 23:38:19 2011 -0700 files: Misc/NEWS description: Issue #12540: Prevent zombie IDLE processes on Windows due to changes in os.kill(). Original patch by Eli Bendersky. diff -r 210d9a2dab09 -r c2fd1ce1c6d4 Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py Thu Aug 04 22:43:11 2011 -0700 +++ b/Lib/idlelib/PyShell.py Thu Aug 04 23:38:19 2011 -0700 @@ -10,6 +10,7 @@ import threading import traceback import types +import subprocess import linecache from code import InteractiveInterpreter @@ -37,11 +38,6 @@ HOST = '127.0.0.1' # python execution server on localhost loopback PORT = 0 # someday pass in host, port for remote debug capability -try: - from signal import SIGTERM -except ImportError: - SIGTERM = 15 - # Override warnings module to write to warning_stream. Initialize to send IDLE # internal warnings to the console. ScriptBinding.check_syntax() will # temporarily redirect the stream to the shell window to display warnings when @@ -344,13 +340,12 @@ self.port = PORT rpcclt = None - rpcpid = None + rpcsubproc = None def spawn_subprocess(self): if self.subprocess_arglist is None: self.subprocess_arglist = self.build_subprocess_arglist() - args = self.subprocess_arglist - self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) + self.rpcsubproc = subprocess.Popen(self.subprocess_arglist) def build_subprocess_arglist(self): assert (self.port!=0), ( @@ -365,12 +360,7 @@ command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) else: command = "__import__('run').main(%r)" % (del_exitf,) - if sys.platform[:3] == 'win' and ' ' in sys.executable: - # handle embedded space in path by quoting the argument - decorated_exec = '"%s"' % sys.executable - else: - decorated_exec = sys.executable - return [decorated_exec] + w + ["-c", command, str(self.port)] + return [sys.executable] + w + ["-c", command, str(self.port)] def start_subprocess(self): addr = (HOST, self.port) @@ -428,7 +418,7 @@ pass # Kill subprocess, spawn a new one, accept connection. self.rpcclt.close() - self.unix_terminate() + self.terminate_subprocess() console = self.tkconsole was_executing = console.executing console.executing = False @@ -469,23 +459,22 @@ self.rpcclt.close() except AttributeError: # no socket pass - self.unix_terminate() + self.terminate_subprocess() self.tkconsole.executing = False self.rpcclt = None - def unix_terminate(self): - "UNIX: make sure subprocess is terminated and collect status" - if hasattr(os, 'kill'): + def terminate_subprocess(self): + "Make sure subprocess is terminated" + try: + self.rpcsubproc.kill() + except OSError: + # process already terminated + return + else: try: - os.kill(self.rpcpid, SIGTERM) + self.rpcsubproc.wait() except OSError: - # process already terminated: return - else: - try: - os.waitpid(self.rpcpid, 0) - except OSError: - return def transfer_path(self): self.runcommand("""if 1: diff -r 210d9a2dab09 -r c2fd1ce1c6d4 Misc/NEWS --- a/Misc/NEWS Thu Aug 04 22:43:11 2011 -0700 +++ b/Misc/NEWS Thu Aug 04 23:38:19 2011 -0700 @@ -249,6 +249,9 @@ Library ------- +- Issue #12540: Prevent zombie IDLE processes on Windows due to changes + in os.kill(). + - Issue #12683: urlparse updated to include svn as schemes that uses relative paths. (svn from 1.5 onwards support relative path). /nad@acm.org