Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e866c81

Browse files
committed
Merged revisions 71126 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r71126 | kurt.kaiser | 2009-04-04 03:03:48 -0400 (Sat, 04 Apr 2009) | 5 lines Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to David Scherer for suggesting the use of an ephemeral port for the GUI. Patch 1529142 Weeble. ........
1 parent 88f1435 commit e866c81

3 files changed

Lines changed: 34 additions & 19 deletions

File tree

Lib/idlelib/NEWS.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ What's New in IDLE 3.1a1?
33

44
*Release date: XX-XXX-XXXX*
55

6+
- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to
7+
David Scherer for suggesting the use of an ephemeral port for the GUI.
8+
Patch 1529142 Weeble.
9+
610
- Remove port spec from run.py and fix bug where subprocess fails to
711
extract port from command line when warnings are present.
812

Lib/idlelib/PyShell.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
from idlelib import RemoteDebugger
3535
from idlelib import macosxSupport
3636

37-
LOCALHOST = '127.0.0.1'
37+
HOST = '127.0.0.1' # python execution server on localhost loopback
38+
PORT = 0 # someday pass in host, port for remote debug capability
3839

3940
try:
4041
from signal import SIGTERM
@@ -339,17 +340,21 @@ def __init__(self, tkconsole):
339340
InteractiveInterpreter.__init__(self, locals=locals)
340341
self.save_warnings_filters = None
341342
self.restarting = False
342-
self.subprocess_arglist = self.build_subprocess_arglist()
343+
self.subprocess_arglist = None
344+
self.port = PORT
343345

344-
port = 8833
345346
rpcclt = None
346347
rpcpid = None
347348

348349
def spawn_subprocess(self):
350+
if self.subprocess_arglist == None:
351+
self.subprocess_arglist = self.build_subprocess_arglist()
349352
args = self.subprocess_arglist
350353
self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
351354

352355
def build_subprocess_arglist(self):
356+
assert (self.port!=0), (
357+
"Socket should have been assigned a port number.")
353358
w = ['-W' + s for s in sys.warnoptions]
354359
# Maybe IDLE is installed and is being accessed via sys.path,
355360
# or maybe it's not installed and the idle.py script is being
@@ -368,11 +373,8 @@ def build_subprocess_arglist(self):
368373
return [decorated_exec] + w + ["-c", command, str(self.port)]
369374

370375
def start_subprocess(self):
371-
# spawning first avoids passing a listening socket to the subprocess
372-
self.spawn_subprocess()
373-
#time.sleep(20) # test to simulate GUI not accepting connection
374-
addr = (LOCALHOST, self.port)
375-
# Idle starts listening for connection on localhost
376+
addr = (HOST, self.port)
377+
# GUI makes several attempts to acquire socket, listens for connection
376378
for i in range(3):
377379
time.sleep(i)
378380
try:
@@ -383,6 +385,18 @@ def start_subprocess(self):
383385
else:
384386
self.display_port_binding_error()
385387
return None
388+
# if PORT was 0, system will assign an 'ephemeral' port. Find it out:
389+
self.port = self.rpcclt.listening_sock.getsockname()[1]
390+
# if PORT was not 0, probably working with a remote execution server
391+
if PORT != 0:
392+
# To allow reconnection within the 2MSL wait (cf. Stevens TCP
393+
# V1, 18.6), set SO_REUSEADDR. Note that this can be problematic
394+
# on Windows since the implementation allows two active sockets on
395+
# the same address!
396+
self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET,
397+
socket.SO_REUSEADDR, 1)
398+
self.spawn_subprocess()
399+
#time.sleep(20) # test to simulate GUI not accepting connection
386400
# Accept the connection from the Python execution server
387401
self.rpcclt.listening_sock.settimeout(10)
388402
try:
@@ -734,13 +748,12 @@ def write(self, s):
734748
def display_port_binding_error(self):
735749
tkMessageBox.showerror(
736750
"Port Binding Error",
737-
"IDLE can't bind TCP/IP port 8833, which is necessary to "
738-
"communicate with its Python execution server. Either "
739-
"no networking is installed on this computer or another "
740-
"process (another IDLE?) is using the port. Run IDLE with the -n "
741-
"command line switch to start without a subprocess and refer to "
742-
"Help/IDLE Help 'Running without a subprocess' for further "
743-
"details.",
751+
"IDLE can't bind to a TCP/IP port, which is necessary to "
752+
"communicate with its Python execution server. This might be "
753+
"because no networking is installed on this computer. "
754+
"Run IDLE with the -n command line switch to start without a "
755+
"subprocess and refer to Help/IDLE Help 'Running without a "
756+
"subprocess' for further details.",
744757
master=self.tkconsole.text)
745758

746759
def display_no_subprocess_error(self):
@@ -1285,7 +1298,7 @@ def main():
12851298
global flist, root, use_subprocess
12861299

12871300
use_subprocess = True
1288-
enable_shell = False
1301+
enable_shell = True
12891302
enable_edit = False
12901303
debug = False
12911304
cmd = None
@@ -1306,6 +1319,7 @@ def main():
13061319
enable_shell = True
13071320
if o == '-e':
13081321
enable_edit = True
1322+
enable_shell = False
13091323
if o == '-h':
13101324
sys.stdout.write(usage_msg)
13111325
sys.exit()
@@ -1356,7 +1370,6 @@ def main():
13561370
edit_start = idleConf.GetOption('main', 'General',
13571371
'editor-on-startup', type='bool')
13581372
enable_edit = enable_edit or edit_start
1359-
enable_shell = enable_shell or not edit_start
13601373
# start editor and/or shell windows:
13611374
root = Tk(className="Idle")
13621375

Lib/idlelib/rpc.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,6 @@ class RPCClient(SocketIO):
518518

519519
def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM):
520520
self.listening_sock = socket.socket(family, type)
521-
self.listening_sock.setsockopt(socket.SOL_SOCKET,
522-
socket.SO_REUSEADDR, 1)
523521
self.listening_sock.bind(address)
524522
self.listening_sock.listen(1)
525523

0 commit comments

Comments
 (0)