3434from idlelib import RemoteDebugger
3535from 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
3940try :
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
0 commit comments