blob: b6205ca689446537b4a7f3567aa47ada383fbdbf [file] [log] [blame]
David Scherer7aced172000-08-15 01:13:23 +00001#! /usr/bin/env python
2
David Scherer7aced172000-08-15 01:13:23 +00003import os
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +00004import os.path
David Scherer7aced172000-08-15 01:13:23 +00005import sys
6import string
7import getopt
8import re
Chui Tey5d2af632002-05-26 13:36:41 +00009import socket
10import time
Kurt B. Kaiser003091c2003-02-17 18:57:16 +000011import threading
Chui Tey5d2af632002-05-26 13:36:41 +000012import traceback
Kurt B. Kaiser62833982002-09-18 17:07:05 +000013import types
Kurt B. Kaiser0930c432002-12-06 21:45:24 +000014import exceptions
David Scherer7aced172000-08-15 01:13:23 +000015
16import linecache
17from code import InteractiveInterpreter
18
Kurt B. Kaiser2303b1c2003-11-24 05:26:16 +000019try:
20 from Tkinter import *
21except ImportError:
22 print>>sys.__stderr__, "** IDLE can't import Tkinter. " \
23 "Your Python may not be configured for Tk. **"
24 sys.exit(1)
David Scherer7aced172000-08-15 01:13:23 +000025import tkMessageBox
26
27from EditorWindow import EditorWindow, fixwordbreaks
28from FileList import FileList
29from ColorDelegator import ColorDelegator
30from UndoDelegator import UndoDelegator
Kurt B. Kaiser969de452002-06-12 03:28:57 +000031from OutputWindow import OutputWindow
Steven M. Gava99300612001-11-04 07:03:08 +000032from configHandler import idleConf
David Scherer7aced172000-08-15 01:13:23 +000033import idlever
34
Chui Tey5d2af632002-05-26 13:36:41 +000035import rpc
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +000036import Debugger
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000037import RemoteDebugger
Chui Tey5d2af632002-05-26 13:36:41 +000038
Kurt B. Kaiserb9764192002-09-23 04:10:37 +000039IDENTCHARS = string.ascii_letters + string.digits + "_"
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +000040LOCALHOST = '127.0.0.1'
Kurt B. Kaiserb9764192002-09-23 04:10:37 +000041
Kurt B. Kaisera00050f2003-05-08 20:26:55 +000042try:
43 from signal import SIGTERM
44except ImportError:
45 SIGTERM = 15
46
Chui Tey5d2af632002-05-26 13:36:41 +000047# Change warnings module to write to sys.__stderr__
48try:
49 import warnings
50except ImportError:
51 pass
52else:
53 def idle_showwarning(message, category, filename, lineno):
54 file = sys.__stderr__
55 file.write(warnings.formatwarning(message, category, filename, lineno))
56 warnings.showwarning = idle_showwarning
57
Kurt B. Kaiser81885592002-11-29 22:10:53 +000058def extended_linecache_checkcache(orig_checkcache=linecache.checkcache):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000059 """Extend linecache.checkcache to preserve the <pyshell#...> entries
60
Kurt B. Kaiser81885592002-11-29 22:10:53 +000061 Rather than repeating the linecache code, patch it to save the pyshell#
62 entries, call the original linecache.checkcache(), and then restore the
63 saved entries. Assigning the orig_checkcache keyword arg freezes its value
64 at definition time to the (original) method linecache.checkcache(), i.e.
65 makes orig_checkcache lexical.
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000066
67 """
David Scherer7aced172000-08-15 01:13:23 +000068 cache = linecache.cache
69 save = {}
70 for filename in cache.keys():
71 if filename[:1] + filename[-1:] == '<>':
72 save[filename] = cache[filename]
73 orig_checkcache()
74 cache.update(save)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000075
Kurt B. Kaiser81885592002-11-29 22:10:53 +000076# Patch linecache.checkcache():
77linecache.checkcache = extended_linecache_checkcache
David Scherer7aced172000-08-15 01:13:23 +000078
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000079
David Scherer7aced172000-08-15 01:13:23 +000080class PyShellEditorWindow(EditorWindow):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000081 "Regular text edit window when a shell is present"
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000082
David Scherer7aced172000-08-15 01:13:23 +000083 def __init__(self, *args):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000084 self.breakpoints = []
Raymond Hettinger931237e2003-07-09 18:48:24 +000085 EditorWindow.__init__(self, *args)
David Scherer7aced172000-08-15 01:13:23 +000086 self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000087 self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
David Scherer7aced172000-08-15 01:13:23 +000088 self.text.bind("<<open-python-shell>>", self.flist.open_shell)
89
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +000090 self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
91 'breakpoints.lst')
Chui Teya2adb0f2002-11-04 22:14:54 +000092 # whenever a file is changed, restore breakpoints
93 if self.io.filename: self.restore_file_breaks()
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +000094 def filename_changed_hook(old_hook=self.io.filename_change_hook,
95 self=self):
Chui Teya2adb0f2002-11-04 22:14:54 +000096 self.restore_file_breaks()
97 old_hook()
98 self.io.set_filename_change_hook(filename_changed_hook)
99
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000100 rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
101 ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
David Scherer7aced172000-08-15 01:13:23 +0000102
Chui Teya2adb0f2002-11-04 22:14:54 +0000103 def set_breakpoint(self, lineno):
104 text = self.text
105 filename = self.io.filename
106 text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
107 try:
108 i = self.breakpoints.index(lineno)
109 except ValueError: # only add if missing, i.e. do once
110 self.breakpoints.append(lineno)
111 try: # update the subprocess debugger
112 debug = self.flist.pyshell.interp.debugger
113 debug.set_breakpoint_here(filename, lineno)
114 except: # but debugger may not be active right now....
115 pass
116
David Scherer7aced172000-08-15 01:13:23 +0000117 def set_breakpoint_here(self, event=None):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000118 text = self.text
119 filename = self.io.filename
120 if not filename:
121 text.bell()
David Scherer7aced172000-08-15 01:13:23 +0000122 return
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000123 lineno = int(float(text.index("insert")))
Chui Teya2adb0f2002-11-04 22:14:54 +0000124 self.set_breakpoint(lineno)
David Scherer7aced172000-08-15 01:13:23 +0000125
Kurt B. Kaiser669f4c32002-06-20 04:01:47 +0000126 def clear_breakpoint_here(self, event=None):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000127 text = self.text
128 filename = self.io.filename
129 if not filename:
130 text.bell()
Kurt B. Kaiser669f4c32002-06-20 04:01:47 +0000131 return
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000132 lineno = int(float(text.index("insert")))
133 try:
134 self.breakpoints.remove(lineno)
135 except:
136 pass
137 text.tag_remove("BREAK", "insert linestart",\
138 "insert lineend +1char")
139 try:
140 debug = self.flist.pyshell.interp.debugger
141 debug.clear_breakpoint_here(filename, lineno)
142 except:
143 pass
144
145 def clear_file_breaks(self):
146 if self.breakpoints:
147 text = self.text
148 filename = self.io.filename
149 if not filename:
150 text.bell()
151 return
152 self.breakpoints = []
153 text.tag_remove("BREAK", "1.0", END)
154 try:
155 debug = self.flist.pyshell.interp.debugger
156 debug.clear_file_breaks(filename)
157 except:
158 pass
159
Chui Teya2adb0f2002-11-04 22:14:54 +0000160 def store_file_breaks(self):
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000161 "Save breakpoints when file is saved"
162 # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
163 # be run. The breaks are saved at that time. If we introduce
164 # a temporary file save feature the save breaks functionality
165 # needs to be re-verified, since the breaks at the time the
166 # temp file is created may differ from the breaks at the last
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000167 # permanent save of the file. Currently, a break introduced
168 # after a save will be effective, but not persistent.
169 # This is necessary to keep the saved breaks synched with the
170 # saved file.
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000171 #
172 # Breakpoints are set as tagged ranges in the text. Certain
173 # kinds of edits cause these ranges to be deleted: Inserting
174 # or deleting a line just before a breakpoint, and certain
175 # deletions prior to a breakpoint. These issues need to be
176 # investigated and understood. It's not clear if they are
177 # Tk issues or IDLE issues, or whether they can actually
178 # be fixed. Since a modified file has to be saved before it is
179 # run, and since self.breakpoints (from which the subprocess
180 # debugger is loaded) is updated during the save, the visible
181 # breaks stay synched with the subprocess even if one of these
182 # unexpected breakpoint deletions occurs.
183 breaks = self.breakpoints
184 filename = self.io.filename
Chui Teya2adb0f2002-11-04 22:14:54 +0000185 try:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000186 lines = open(self.breakpointPath,"r").readlines()
Chui Teya2adb0f2002-11-04 22:14:54 +0000187 except IOError:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000188 lines = []
189 new_file = open(self.breakpointPath,"w")
Chui Teya2adb0f2002-11-04 22:14:54 +0000190 for line in lines:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000191 if not line.startswith(filename + '='):
Chui Teya2adb0f2002-11-04 22:14:54 +0000192 new_file.write(line)
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000193 self.update_breakpoints()
194 breaks = self.breakpoints
195 if breaks:
196 new_file.write(filename + '=' + str(breaks) + '\n')
Chui Teya2adb0f2002-11-04 22:14:54 +0000197 new_file.close()
198
199 def restore_file_breaks(self):
200 self.text.update() # this enables setting "BREAK" tags to be visible
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000201 filename = self.io.filename
202 if filename is None:
203 return
Chui Tey69371d62002-11-04 23:39:45 +0000204 if os.path.isfile(self.breakpointPath):
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000205 lines = open(self.breakpointPath,"r").readlines()
Chui Tey69371d62002-11-04 23:39:45 +0000206 for line in lines:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000207 if line.startswith(filename + '='):
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000208 breakpoint_linenumbers = eval(line[len(filename)+1:])
Chui Tey69371d62002-11-04 23:39:45 +0000209 for breakpoint_linenumber in breakpoint_linenumbers:
210 self.set_breakpoint(breakpoint_linenumber)
Chui Teya2adb0f2002-11-04 22:14:54 +0000211
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000212 def update_breakpoints(self):
213 "Retrieves all the breakpoints in the current window"
Chui Teya2adb0f2002-11-04 22:14:54 +0000214 text = self.text
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000215 ranges = text.tag_ranges("BREAK")
216 linenumber_list = self.ranges_to_linenumbers(ranges)
217 self.breakpoints = linenumber_list
218
219 def ranges_to_linenumbers(self, ranges):
220 lines = []
221 for index in range(0, len(ranges), 2):
222 lineno = int(float(ranges[index]))
223 end = int(float(ranges[index+1]))
224 while lineno < end:
225 lines.append(lineno)
226 lineno += 1
227 return lines
228
Kurt B. Kaiser11220fa2002-12-24 00:57:22 +0000229# XXX 13 Dec 2002 KBK Not used currently
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000230# def saved_change_hook(self):
231# "Extend base method - clear breaks if module is modified"
232# if not self.get_saved():
233# self.clear_file_breaks()
234# EditorWindow.saved_change_hook(self)
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000235
236 def _close(self):
237 "Extend base method - clear breaks when module is closed"
238 self.clear_file_breaks()
239 EditorWindow._close(self)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000240
David Scherer7aced172000-08-15 01:13:23 +0000241
242class PyShellFileList(FileList):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000243 "Extend base class: file list when a shell is present"
David Scherer7aced172000-08-15 01:13:23 +0000244
245 EditorWindow = PyShellEditorWindow
246
247 pyshell = None
248
249 def open_shell(self, event=None):
250 if self.pyshell:
251 self.pyshell.wakeup()
252 else:
253 self.pyshell = PyShell(self)
254 self.pyshell.begin()
255 return self.pyshell
256
257
258class ModifiedColorDelegator(ColorDelegator):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000259 "Extend base class: colorizer for the shell window itself"
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000260
Steven M. Gavab77d3432002-03-02 07:16:21 +0000261 def __init__(self):
262 ColorDelegator.__init__(self)
263 self.LoadTagDefs()
David Scherer7aced172000-08-15 01:13:23 +0000264
265 def recolorize_main(self):
266 self.tag_remove("TODO", "1.0", "iomark")
267 self.tag_add("SYNC", "1.0", "iomark")
268 ColorDelegator.recolorize_main(self)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000269
Steven M. Gavab77d3432002-03-02 07:16:21 +0000270 def LoadTagDefs(self):
271 ColorDelegator.LoadTagDefs(self)
272 theme = idleConf.GetOption('main','Theme','name')
273 self.tagdefs.update({
274 "stdin": {'background':None,'foreground':None},
275 "stdout": idleConf.GetHighlight(theme, "stdout"),
276 "stderr": idleConf.GetHighlight(theme, "stderr"),
277 "console": idleConf.GetHighlight(theme, "console"),
Steven M. Gavab77d3432002-03-02 07:16:21 +0000278 None: idleConf.GetHighlight(theme, "normal"),
279 })
David Scherer7aced172000-08-15 01:13:23 +0000280
David Scherer7aced172000-08-15 01:13:23 +0000281class ModifiedUndoDelegator(UndoDelegator):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000282 "Extend base class: forbid insert/delete before the I/O mark"
David Scherer7aced172000-08-15 01:13:23 +0000283
284 def insert(self, index, chars, tags=None):
285 try:
286 if self.delegate.compare(index, "<", "iomark"):
287 self.delegate.bell()
288 return
289 except TclError:
290 pass
291 UndoDelegator.insert(self, index, chars, tags)
292
293 def delete(self, index1, index2=None):
294 try:
295 if self.delegate.compare(index1, "<", "iomark"):
296 self.delegate.bell()
297 return
298 except TclError:
299 pass
300 UndoDelegator.delete(self, index1, index2)
301
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000302
303class MyRPCClient(rpc.RPCClient):
304
305 def handle_EOF(self):
306 "Override the base class - just re-raise EOFError"
307 raise EOFError
308
Kurt B. Kaiser8d1f11b2003-05-26 22:20:34 +0000309
David Scherer7aced172000-08-15 01:13:23 +0000310class ModifiedInterpreter(InteractiveInterpreter):
311
312 def __init__(self, tkconsole):
313 self.tkconsole = tkconsole
314 locals = sys.modules['__main__'].__dict__
315 InteractiveInterpreter.__init__(self, locals=locals)
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000316 self.save_warnings_filters = None
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000317 self.restarting = False
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000318 self.subprocess_arglist = self.build_subprocess_arglist()
David Scherer7aced172000-08-15 01:13:23 +0000319
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000320 port = 8833
Chui Tey5d2af632002-05-26 13:36:41 +0000321 rpcclt = None
322 rpcpid = None
323
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000324 def spawn_subprocess(self):
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000325 args = self.subprocess_arglist
Kurt B. Kaiserb7855182003-08-14 14:54:28 +0000326 self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000327
Tony Lowndsf53dec22002-12-20 04:24:43 +0000328 def build_subprocess_arglist(self):
Tony Lownds2398d572003-05-13 15:28:21 +0000329 w = ['-W' + s for s in sys.warnoptions]
330 # Maybe IDLE is installed and is being accessed via sys.path,
331 # or maybe it's not installed and the idle.py script is being
332 # run from the IDLE source directory.
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000333 del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
334 default=False, type='bool')
Tony Lownds2398d572003-05-13 15:28:21 +0000335 if __name__ == 'idlelib.PyShell':
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000336 command = "__import__('idlelib.run').run.main(" + `del_exitf` +")"
Tony Lowndsf2324b92002-09-29 00:34:10 +0000337 else:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000338 command = "__import__('run').main(" + `del_exitf` + ")"
Kurt B. Kaiserb7855182003-08-14 14:54:28 +0000339 if sys.platform[:3] == 'win' and ' ' in sys.executable:
340 # handle embedded space in path by quoting the argument
341 decorated_exec = '"%s"' % sys.executable
342 else:
343 decorated_exec = sys.executable
344 return [decorated_exec] + w + ["-c", command, str(self.port)]
Tony Lowndsf2324b92002-09-29 00:34:10 +0000345
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000346 def start_subprocess(self):
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +0000347 addr = (LOCALHOST, self.port)
Kurt B. Kaiser8dcdb772002-08-05 03:52:10 +0000348 # Idle starts listening for connection on localhost
Kurt B. Kaiser5db48432003-05-15 03:40:51 +0000349 for i in range(3):
Chui Tey5d2af632002-05-26 13:36:41 +0000350 time.sleep(i)
351 try:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000352 self.rpcclt = MyRPCClient(addr)
Chui Tey5d2af632002-05-26 13:36:41 +0000353 break
354 except socket.error, err:
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000355 print>>sys.__stderr__,"IDLE socket error: " + err[1]\
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000356 + ", retrying..."
Chui Tey5d2af632002-05-26 13:36:41 +0000357 else:
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000358 display_port_binding_error()
Kurt B. Kaisera2a3cb22002-12-24 03:33:12 +0000359 sys.exit()
Kurt B. Kaiser5db48432003-05-15 03:40:51 +0000360 self.spawn_subprocess()
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000361 # Accept the connection from the Python execution server
362 self.rpcclt.accept()
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000363 self.rpcclt.register("stdin", self.tkconsole)
364 self.rpcclt.register("stdout", self.tkconsole.stdout)
365 self.rpcclt.register("stderr", self.tkconsole.stderr)
Chui Tey5d2af632002-05-26 13:36:41 +0000366 self.rpcclt.register("flist", self.tkconsole.flist)
Kurt B. Kaiser8cd0def2003-01-31 05:06:43 +0000367 self.rpcclt.register("linecache", linecache)
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000368 self.rpcclt.register("interp", self)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000369 self.transfer_path()
Chui Tey5d2af632002-05-26 13:36:41 +0000370 self.poll_subprocess()
371
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000372 def restart_subprocess(self):
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000373 if self.restarting:
374 return
375 self.restarting = True
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000376 # close only the subprocess debugger
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000377 debug = self.getdebugger()
378 if debug:
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000379 try:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000380 # Only close subprocess debugger, don't unregister gui_adap!
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000381 RemoteDebugger.close_subprocess_debugger(self.rpcclt)
382 except:
383 pass
384 # Kill subprocess, spawn a new one, accept connection.
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000385 self.rpcclt.close()
386 self.unix_terminate()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000387 console = self.tkconsole
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000388 was_executing = console.executing
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000389 console.executing = False
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000390 self.spawn_subprocess()
391 self.rpcclt.accept()
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000392 self.transfer_path()
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000393 # annotate restart in shell window and mark it
Kurt B. Kaiser4cc5ef52003-01-22 00:23:23 +0000394 console.text.delete("iomark", "end-1c")
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000395 if was_executing:
396 console.write('\n')
397 console.showprompt()
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000398 halfbar = ((int(console.width) - 16) // 2) * '='
399 console.write(halfbar + ' RESTART ' + halfbar)
400 console.text.mark_set("restart", "end-1c")
401 console.text.mark_gravity("restart", "left")
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000402 console.showprompt()
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000403 # restart subprocess debugger
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000404 if debug:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000405 # Restarted debugger connects to current instance of debug GUI
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000406 gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000407 # reload remote debugger breakpoints for all PyShellEditWindows
408 debug.load_breakpoints()
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000409 self.restarting = False
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000410
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000411 def __request_interrupt(self):
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000412 self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000413
414 def interrupt_subprocess(self):
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000415 threading.Thread(target=self.__request_interrupt).start()
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000416
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000417 def kill_subprocess(self):
418 self.rpcclt.close()
419 self.unix_terminate()
420 self.tkconsole.executing = False
421 self.rpcclt = None
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000422
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000423 def unix_terminate(self):
424 "UNIX: make sure subprocess is terminated and collect status"
425 if hasattr(os, 'kill'):
426 try:
427 os.kill(self.rpcpid, SIGTERM)
428 except OSError:
429 # process already terminated:
430 return
431 else:
432 try:
433 os.waitpid(self.rpcpid, 0)
434 except OSError:
435 return
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000436
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000437 def transfer_path(self):
438 self.runcommand("""if 1:
439 import sys as _sys
440 _sys.path = %s
441 del _sys
Kurt B. Kaiserb2487332003-03-04 04:03:45 +0000442 _msg = 'Use File/Exit or your end-of-file key to quit IDLE'
443 __builtins__.quit = __builtins__.exit = _msg
444 del _msg
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000445 \n""" % `sys.path`)
446
Chui Tey5d2af632002-05-26 13:36:41 +0000447 active_seq = None
448
449 def poll_subprocess(self):
450 clt = self.rpcclt
451 if clt is None:
452 return
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000453 try:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000454 response = clt.pollresponse(self.active_seq, wait=0.05)
455 except (EOFError, IOError, KeyboardInterrupt):
456 # lost connection or subprocess terminated itself, restart
457 # [the KBI is from rpc.SocketIO.handle_EOF()]
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000458 if self.tkconsole.closing:
459 return
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000460 response = None
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000461 self.restart_subprocess()
Chui Tey5d2af632002-05-26 13:36:41 +0000462 if response:
463 self.tkconsole.resetoutput()
464 self.active_seq = None
465 how, what = response
Kurt B. Kaiserbc286132003-01-25 21:33:40 +0000466 console = self.tkconsole.console
Chui Tey5d2af632002-05-26 13:36:41 +0000467 if how == "OK":
468 if what is not None:
Kurt B. Kaiserbc286132003-01-25 21:33:40 +0000469 print >>console, `what`
Chui Tey5d2af632002-05-26 13:36:41 +0000470 elif how == "EXCEPTION":
Chui Tey5d2af632002-05-26 13:36:41 +0000471 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
472 self.remote_stack_viewer()
473 elif how == "ERROR":
Kurt B. Kaiser0930c432002-12-06 21:45:24 +0000474 errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
475 print >>sys.__stderr__, errmsg, what
Kurt B. Kaiserbc286132003-01-25 21:33:40 +0000476 print >>console, errmsg, what
477 # we received a response to the currently active seq number:
Chui Tey5d2af632002-05-26 13:36:41 +0000478 self.tkconsole.endexecuting()
Kurt B. Kaiser88957d82003-05-19 23:11:51 +0000479 # Reschedule myself
480 if not self.tkconsole.closing:
481 self.tkconsole.text.after(self.tkconsole.pollinterval,
482 self.poll_subprocess)
Chui Tey5d2af632002-05-26 13:36:41 +0000483
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000484 debugger = None
485
486 def setdebugger(self, debugger):
487 self.debugger = debugger
488
489 def getdebugger(self):
490 return self.debugger
491
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000492 def open_remote_stack_viewer(self):
493 """Initiate the remote stack viewer from a separate thread.
494
495 This method is called from the subprocess, and by returning from this
496 method we allow the subprocess to unblock. After a bit the shell
497 requests the subprocess to open the remote stack viewer which returns a
498 static object looking at the last exceptiopn. It is queried through
499 the RPC mechanism.
500
501 """
502 self.tkconsole.text.after(300, self.remote_stack_viewer)
503 return
504
Chui Tey5d2af632002-05-26 13:36:41 +0000505 def remote_stack_viewer(self):
506 import RemoteObjectBrowser
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000507 oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
Chui Tey5d2af632002-05-26 13:36:41 +0000508 if oid is None:
509 self.tkconsole.root.bell()
510 return
511 item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
512 from TreeWidget import ScrolledCanvas, TreeNode
513 top = Toplevel(self.tkconsole.root)
514 sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
515 sc.frame.pack(expand=1, fill="both")
516 node = TreeNode(sc.canvas, None, item)
517 node.expand()
518 # XXX Should GC the remote tree when closing the window
519
David Scherer7aced172000-08-15 01:13:23 +0000520 gid = 0
521
522 def execsource(self, source):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000523 "Like runsource() but assumes complete exec source"
David Scherer7aced172000-08-15 01:13:23 +0000524 filename = self.stuffsource(source)
525 self.execfile(filename, source)
526
527 def execfile(self, filename, source=None):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000528 "Execute an existing file"
David Scherer7aced172000-08-15 01:13:23 +0000529 if source is None:
530 source = open(filename, "r").read()
531 try:
532 code = compile(source, filename, "exec")
533 except (OverflowError, SyntaxError):
534 self.tkconsole.resetoutput()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000535 tkerr = self.tkconsole.stderr
536 print>>tkerr, '*** Error in script or command!\n'
537 print>>tkerr, 'Traceback (most recent call last):'
David Scherer7aced172000-08-15 01:13:23 +0000538 InteractiveInterpreter.showsyntaxerror(self, filename)
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +0000539 self.tkconsole.showprompt()
David Scherer7aced172000-08-15 01:13:23 +0000540 else:
541 self.runcode(code)
542
543 def runsource(self, source):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000544 "Extend base class method: Stuff the source in the line cache first"
David Scherer7aced172000-08-15 01:13:23 +0000545 filename = self.stuffsource(source)
546 self.more = 0
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000547 self.save_warnings_filters = warnings.filters[:]
548 warnings.filterwarnings(action="error", category=SyntaxWarning)
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000549 if isinstance(source, types.UnicodeType):
550 import IOBinding
551 try:
552 source = source.encode(IOBinding.encoding)
553 except UnicodeError:
554 self.tkconsole.resetoutput()
555 self.write("Unsupported characters in input")
556 return
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000557 try:
558 return InteractiveInterpreter.runsource(self, source, filename)
559 finally:
560 if self.save_warnings_filters is not None:
561 warnings.filters[:] = self.save_warnings_filters
562 self.save_warnings_filters = None
David Scherer7aced172000-08-15 01:13:23 +0000563
564 def stuffsource(self, source):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000565 "Stuff source in the filename cache"
David Scherer7aced172000-08-15 01:13:23 +0000566 filename = "<pyshell#%d>" % self.gid
567 self.gid = self.gid + 1
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000568 lines = source.split("\n")
David Scherer7aced172000-08-15 01:13:23 +0000569 linecache.cache[filename] = len(source)+1, 0, lines, filename
570 return filename
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000571
Kurt B. Kaiser11659ad2003-05-15 23:23:21 +0000572 def prepend_syspath(self, filename):
573 "Prepend sys.path with file's directory if not already included"
574 self.runcommand("""if 1:
575 _filename = %s
576 import sys as _sys
577 from os.path import dirname as _dirname
578 _dir = _dirname(_filename)
579 if not _dir in _sys.path:
580 _sys.path.insert(0, _dir)
581 del _filename, _sys, _dirname, _dir
582 \n""" % `filename`)
583
David Scherer7aced172000-08-15 01:13:23 +0000584 def showsyntaxerror(self, filename=None):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000585 """Extend base class method: Add Colorizing
586
587 Color the offending position instead of printing it and pointing at it
588 with a caret.
589
590 """
David Scherer7aced172000-08-15 01:13:23 +0000591 text = self.tkconsole.text
592 stuff = self.unpackerror()
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +0000593 if stuff:
594 msg, lineno, offset, line = stuff
595 if lineno == 1:
596 pos = "iomark + %d chars" % (offset-1)
597 else:
598 pos = "iomark linestart + %d lines + %d chars" % \
599 (lineno-1, offset-1)
600 text.tag_add("ERROR", pos)
601 text.see(pos)
602 char = text.get(pos)
603 if char and char in IDENTCHARS:
604 text.tag_add("ERROR", pos + " wordstart", pos)
605 self.tkconsole.resetoutput()
606 self.write("SyntaxError: %s\n" % str(msg))
607 else:
David Scherer7aced172000-08-15 01:13:23 +0000608 self.tkconsole.resetoutput()
609 InteractiveInterpreter.showsyntaxerror(self, filename)
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +0000610 self.tkconsole.showprompt()
David Scherer7aced172000-08-15 01:13:23 +0000611
612 def unpackerror(self):
613 type, value, tb = sys.exc_info()
614 ok = type is SyntaxError
615 if ok:
616 try:
617 msg, (dummy_filename, lineno, offset, line) = value
Kurt B. Kaiserbea57c62003-07-09 04:27:24 +0000618 if not offset:
619 offset = 0
David Scherer7aced172000-08-15 01:13:23 +0000620 except:
621 ok = 0
622 if ok:
623 return msg, lineno, offset, line
624 else:
625 return None
626
627 def showtraceback(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000628 "Extend base class method to reset output properly"
David Scherer7aced172000-08-15 01:13:23 +0000629 self.tkconsole.resetoutput()
630 self.checklinecache()
631 InteractiveInterpreter.showtraceback(self)
Chui Tey5d2af632002-05-26 13:36:41 +0000632 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
633 self.tkconsole.open_stack_viewer()
David Scherer7aced172000-08-15 01:13:23 +0000634
635 def checklinecache(self):
636 c = linecache.cache
637 for key in c.keys():
638 if key[:1] + key[-1:] != "<>":
639 del c[key]
640
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000641 def display_executing_dialog(self):
642 tkMessageBox.showerror(
643 "Already executing",
644 "The Python Shell window is already executing a command; "
645 "please wait until it is finished.",
646 master=self.tkconsole.text)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000647
Chui Tey5d2af632002-05-26 13:36:41 +0000648 def runcommand(self, code):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000649 "Run the code without invoking the debugger"
Chui Tey5d2af632002-05-26 13:36:41 +0000650 # The code better not raise an exception!
651 if self.tkconsole.executing:
Neal Norwitzf4c4f112002-11-30 18:49:10 +0000652 self.display_executing_dialog()
Chui Tey5d2af632002-05-26 13:36:41 +0000653 return 0
654 if self.rpcclt:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000655 self.rpcclt.remotequeue("exec", "runcode", (code,), {})
Chui Tey5d2af632002-05-26 13:36:41 +0000656 else:
657 exec code in self.locals
658 return 1
659
David Scherer7aced172000-08-15 01:13:23 +0000660 def runcode(self, code):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000661 "Override base class method"
Chui Tey5d2af632002-05-26 13:36:41 +0000662 if self.tkconsole.executing:
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000663 self.interp.restart_subprocess()
Chui Tey5d2af632002-05-26 13:36:41 +0000664 self.checklinecache()
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000665 if self.save_warnings_filters is not None:
666 warnings.filters[:] = self.save_warnings_filters
667 self.save_warnings_filters = None
David Scherer7aced172000-08-15 01:13:23 +0000668 debugger = self.debugger
669 try:
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000670 self.tkconsole.beginexecuting()
671 try:
672 if not debugger and self.rpcclt is not None:
673 self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
674 (code,), {})
675 elif debugger:
676 debugger.run(code, self.locals)
677 else:
678 exec code in self.locals
679 except SystemExit:
680 if tkMessageBox.askyesno(
681 "Exit?",
682 "Do you want to exit altogether?",
683 default="yes",
684 master=self.tkconsole.text):
685 raise
686 else:
687 self.showtraceback()
688 except:
David Scherer7aced172000-08-15 01:13:23 +0000689 self.showtraceback()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000690 finally:
691 if not use_subprocess:
692 self.tkconsole.endexecuting()
David Scherer7aced172000-08-15 01:13:23 +0000693
694 def write(self, s):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000695 "Override base class method"
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000696 self.tkconsole.stderr.write(s)
David Scherer7aced172000-08-15 01:13:23 +0000697
David Scherer7aced172000-08-15 01:13:23 +0000698class PyShell(OutputWindow):
699
700 shell_title = "Python Shell"
701
702 # Override classes
703 ColorDelegator = ModifiedColorDelegator
704 UndoDelegator = ModifiedUndoDelegator
705
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000706 # Override menus
Kurt B. Kaiserdc1e7092002-07-11 04:33:41 +0000707 menu_specs = [
708 ("file", "_File"),
709 ("edit", "_Edit"),
Kurt B. Kaiser4cc5ef52003-01-22 00:23:23 +0000710 ("debug", "_Debug"),
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000711 ("options", "_Options"),
Kurt B. Kaiserdc1e7092002-07-11 04:33:41 +0000712 ("windows", "_Windows"),
713 ("help", "_Help"),
714 ]
David Scherer7aced172000-08-15 01:13:23 +0000715
716 # New classes
717 from IdleHistory import History
718
719 def __init__(self, flist=None):
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000720 if use_subprocess:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000721 ms = self.menu_specs
722 if ms[2][0] != "shell":
723 ms.insert(2, ("shell", "_Shell"))
David Scherer7aced172000-08-15 01:13:23 +0000724 self.interp = ModifiedInterpreter(self)
725 if flist is None:
726 root = Tk()
727 fixwordbreaks(root)
728 root.withdraw()
729 flist = PyShellFileList(root)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000730 #
David Scherer7aced172000-08-15 01:13:23 +0000731 OutputWindow.__init__(self, flist, None, None)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000732 #
David Scherer7aced172000-08-15 01:13:23 +0000733 import __builtin__
734 __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000735 #
Kurt B. Kaiseree7afca2002-09-14 02:50:56 +0000736 self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000737 #
David Scherer7aced172000-08-15 01:13:23 +0000738 text = self.text
739 text.configure(wrap="char")
740 text.bind("<<newline-and-indent>>", self.enter_callback)
741 text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
742 text.bind("<<interrupt-execution>>", self.cancel_callback)
743 text.bind("<<beginning-of-line>>", self.home_callback)
744 text.bind("<<end-of-file>>", self.eof_callback)
745 text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
Kurt B. Kaiser57bfe5d2003-05-10 00:09:52 +0000746 text.bind("<<toggle-debugger>>", self.toggle_debugger)
David Scherer7aced172000-08-15 01:13:23 +0000747 text.bind("<<open-python-shell>>", self.flist.open_shell)
748 text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000749 if use_subprocess:
750 text.bind("<<view-restart>>", self.view_restart_mark)
751 text.bind("<<restart-shell>>", self.restart_shell)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000752 #
David Scherer7aced172000-08-15 01:13:23 +0000753 self.save_stdout = sys.stdout
754 self.save_stderr = sys.stderr
755 self.save_stdin = sys.stdin
Martin v. Löwisbcc651a2003-06-22 07:52:56 +0000756 import IOBinding
757 self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
758 self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
759 self.console = PseudoFile(self, "console", IOBinding.encoding)
Chui Tey5d2af632002-05-26 13:36:41 +0000760 if not use_subprocess:
761 sys.stdout = self.stdout
762 sys.stderr = self.stderr
763 sys.stdin = self
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000764 #
David Scherer7aced172000-08-15 01:13:23 +0000765 self.history = self.History(self.text)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000766 #
Kurt B. Kaiser88957d82003-05-19 23:11:51 +0000767 self.pollinterval = 50 # millisec
Chui Tey5d2af632002-05-26 13:36:41 +0000768 if use_subprocess:
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000769 self.interp.start_subprocess()
Chui Tey5d2af632002-05-26 13:36:41 +0000770
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000771 reading = False
772 executing = False
773 canceled = False
774 endoffile = False
775 closing = False
David Scherer7aced172000-08-15 01:13:23 +0000776
777 def toggle_debugger(self, event=None):
778 if self.executing:
779 tkMessageBox.showerror("Don't debug now",
780 "You can only toggle the debugger when idle",
781 master=self.text)
782 self.set_debugger_indicator()
783 return "break"
784 else:
785 db = self.interp.getdebugger()
786 if db:
787 self.close_debugger()
788 else:
789 self.open_debugger()
790
791 def set_debugger_indicator(self):
792 db = self.interp.getdebugger()
793 self.setvar("<<toggle-debugger>>", not not db)
794
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000795 def toggle_jit_stack_viewer(self, event=None):
David Scherer7aced172000-08-15 01:13:23 +0000796 pass # All we need is the variable
797
798 def close_debugger(self):
799 db = self.interp.getdebugger()
800 if db:
801 self.interp.setdebugger(None)
802 db.close()
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000803 if self.interp.rpcclt:
804 RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
David Scherer7aced172000-08-15 01:13:23 +0000805 self.resetoutput()
806 self.console.write("[DEBUG OFF]\n")
807 sys.ps1 = ">>> "
808 self.showprompt()
809 self.set_debugger_indicator()
810
811 def open_debugger(self):
Chui Tey5d2af632002-05-26 13:36:41 +0000812 if self.interp.rpcclt:
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000813 dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
814 self)
815 else:
816 dbg_gui = Debugger.Debugger(self)
817 self.interp.setdebugger(dbg_gui)
818 dbg_gui.load_breakpoints()
Chui Tey5d2af632002-05-26 13:36:41 +0000819 sys.ps1 = "[DEBUG ON]\n>>> "
820 self.showprompt()
821 self.set_debugger_indicator()
822
David Scherer7aced172000-08-15 01:13:23 +0000823 def beginexecuting(self):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000824 "Helper for ModifiedInterpreter"
David Scherer7aced172000-08-15 01:13:23 +0000825 self.resetoutput()
826 self.executing = 1
David Scherer7aced172000-08-15 01:13:23 +0000827
828 def endexecuting(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000829 "Helper for ModifiedInterpreter"
David Scherer7aced172000-08-15 01:13:23 +0000830 self.executing = 0
831 self.canceled = 0
Chui Tey5d2af632002-05-26 13:36:41 +0000832 self.showprompt()
David Scherer7aced172000-08-15 01:13:23 +0000833
834 def close(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000835 "Extend EditorWindow.close()"
David Scherer7aced172000-08-15 01:13:23 +0000836 if self.executing:
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000837 response = tkMessageBox.askokcancel(
David Scherer7aced172000-08-15 01:13:23 +0000838 "Kill?",
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000839 "The program is still running!\n Do you want to kill it?",
David Scherer7aced172000-08-15 01:13:23 +0000840 default="ok",
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000841 parent=self.text)
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000842 if response == False:
David Scherer7aced172000-08-15 01:13:23 +0000843 return "cancel"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000844 self.closing = True
845 # Wait for poll_subprocess() rescheduling to stop
846 self.text.after(2 * self.pollinterval, self.close2)
Kurt B. Kaiser88957d82003-05-19 23:11:51 +0000847
848 def close2(self):
849 return EditorWindow.close(self)
David Scherer7aced172000-08-15 01:13:23 +0000850
851 def _close(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000852 "Extend EditorWindow._close(), shut down debugger and execution server"
David Scherer7aced172000-08-15 01:13:23 +0000853 self.close_debugger()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000854 if use_subprocess:
855 self.interp.kill_subprocess()
David Scherer7aced172000-08-15 01:13:23 +0000856 # Restore std streams
857 sys.stdout = self.save_stdout
858 sys.stderr = self.save_stderr
859 sys.stdin = self.save_stdin
860 # Break cycles
861 self.interp = None
862 self.console = None
David Scherer7aced172000-08-15 01:13:23 +0000863 self.flist.pyshell = None
864 self.history = None
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000865 EditorWindow._close(self)
David Scherer7aced172000-08-15 01:13:23 +0000866
867 def ispythonsource(self, filename):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000868 "Override EditorWindow method: never remove the colorizer"
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000869 return True
David Scherer7aced172000-08-15 01:13:23 +0000870
871 def short_title(self):
872 return self.shell_title
873
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000874 COPYRIGHT = \
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000875 'Type "copyright", "credits" or "license()" for more information.'
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000876
Kurt B. Kaiser220fecf2003-07-27 03:24:19 +0000877 firewallmessage = """
878 ****************************************************************
879 Personal firewall software may warn about the connection IDLE
880 makes to its subprocess using this computer's internal loopback
881 interface. This connection is not visible on any external
882 interface and no data is sent to or received from the Internet.
883 ****************************************************************
884 """
885
David Scherer7aced172000-08-15 01:13:23 +0000886 def begin(self):
887 self.resetoutput()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000888 if use_subprocess:
889 nosub = ''
890 else:
891 nosub = "==== No Subprocess ===="
Kurt B. Kaiser220fecf2003-07-27 03:24:19 +0000892 self.write("Python %s on %s\n%s\n%s\nIDLE %s %s\n" %
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000893 (sys.version, sys.platform, self.COPYRIGHT,
Kurt B. Kaiser220fecf2003-07-27 03:24:19 +0000894 self.firewallmessage, idlever.IDLE_VERSION, nosub))
David Scherer7aced172000-08-15 01:13:23 +0000895 self.showprompt()
896 import Tkinter
897 Tkinter._default_root = None
898
899 def interact(self):
900 self.begin()
901 self.top.mainloop()
902
903 def readline(self):
904 save = self.reading
905 try:
906 self.reading = 1
907 self.top.mainloop()
908 finally:
909 self.reading = save
910 line = self.text.get("iomark", "end-1c")
Martin v. Löwisbcc651a2003-06-22 07:52:56 +0000911 if isinstance(line, unicode):
912 import IOBinding
913 try:
914 line = line.encode(IOBinding.encoding)
915 except UnicodeError:
916 pass
David Scherer7aced172000-08-15 01:13:23 +0000917 self.resetoutput()
918 if self.canceled:
919 self.canceled = 0
920 raise KeyboardInterrupt
921 if self.endoffile:
922 self.endoffile = 0
923 return ""
924 return line
925
926 def isatty(self):
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000927 return True
David Scherer7aced172000-08-15 01:13:23 +0000928
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000929 def cancel_callback(self, event=None):
David Scherer7aced172000-08-15 01:13:23 +0000930 try:
931 if self.text.compare("sel.first", "!=", "sel.last"):
932 return # Active selection -- always use default binding
933 except:
934 pass
935 if not (self.executing or self.reading):
936 self.resetoutput()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000937 self.interp.write("KeyboardInterrupt\n")
David Scherer7aced172000-08-15 01:13:23 +0000938 self.showprompt()
939 return "break"
940 self.endoffile = 0
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000941 self.canceled = 1
David Scherer7aced172000-08-15 01:13:23 +0000942 if self.reading:
943 self.top.quit()
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000944 elif (self.executing and self.interp.rpcclt):
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000945 if self.interp.getdebugger():
946 self.interp.restart_subprocess()
947 else:
948 self.interp.interrupt_subprocess()
David Scherer7aced172000-08-15 01:13:23 +0000949 return "break"
950
951 def eof_callback(self, event):
952 if self.executing and not self.reading:
953 return # Let the default binding (delete next char) take over
954 if not (self.text.compare("iomark", "==", "insert") and
955 self.text.compare("insert", "==", "end-1c")):
956 return # Let the default binding (delete next char) take over
957 if not self.executing:
David Scherer7aced172000-08-15 01:13:23 +0000958 self.resetoutput()
959 self.close()
960 else:
961 self.canceled = 0
962 self.endoffile = 1
963 self.top.quit()
964 return "break"
965
966 def home_callback(self, event):
967 if event.state != 0 and event.keysym == "Home":
968 return # <Modifier-Home>; fall back to class binding
969 if self.text.compare("iomark", "<=", "insert") and \
970 self.text.compare("insert linestart", "<=", "iomark"):
971 self.text.mark_set("insert", "iomark")
972 self.text.tag_remove("sel", "1.0", "end")
973 self.text.see("insert")
974 return "break"
975
976 def linefeed_callback(self, event):
977 # Insert a linefeed without entering anything (still autoindented)
978 if self.reading:
979 self.text.insert("insert", "\n")
980 self.text.see("insert")
981 else:
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +0000982 self.newline_and_indent_event(event)
David Scherer7aced172000-08-15 01:13:23 +0000983 return "break"
984
985 def enter_callback(self, event):
986 if self.executing and not self.reading:
987 return # Let the default binding (insert '\n') take over
988 # If some text is selected, recall the selection
989 # (but only if this before the I/O mark)
990 try:
991 sel = self.text.get("sel.first", "sel.last")
992 if sel:
993 if self.text.compare("sel.last", "<=", "iomark"):
994 self.recall(sel)
995 return "break"
996 except:
997 pass
998 # If we're strictly before the line containing iomark, recall
999 # the current line, less a leading prompt, less leading or
1000 # trailing whitespace
1001 if self.text.compare("insert", "<", "iomark linestart"):
1002 # Check if there's a relevant stdin range -- if so, use it
1003 prev = self.text.tag_prevrange("stdin", "insert")
1004 if prev and self.text.compare("insert", "<", prev[1]):
1005 self.recall(self.text.get(prev[0], prev[1]))
1006 return "break"
1007 next = self.text.tag_nextrange("stdin", "insert")
1008 if next and self.text.compare("insert lineend", ">=", next[0]):
1009 self.recall(self.text.get(next[0], next[1]))
1010 return "break"
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001011 # No stdin mark -- just get the current line, less any prompt
1012 line = self.text.get("insert linestart", "insert lineend")
1013 last_line_of_prompt = sys.ps1.split('\n')[-1]
1014 if line.startswith(last_line_of_prompt):
1015 line = line[len(last_line_of_prompt):]
1016 self.recall(line)
David Scherer7aced172000-08-15 01:13:23 +00001017 return "break"
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001018 # If we're between the beginning of the line and the iomark, i.e.
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001019 # in the prompt area, move to the end of the prompt
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001020 if self.text.compare("insert", "<", "iomark"):
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001021 self.text.mark_set("insert", "iomark")
David Scherer7aced172000-08-15 01:13:23 +00001022 # If we're in the current input and there's only whitespace
1023 # beyond the cursor, erase that whitespace first
1024 s = self.text.get("insert", "end-1c")
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +00001025 if s and not s.strip():
David Scherer7aced172000-08-15 01:13:23 +00001026 self.text.delete("insert", "end-1c")
1027 # If we're in the current input before its last line,
1028 # insert a newline right at the insert point
1029 if self.text.compare("insert", "<", "end-1c linestart"):
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001030 self.newline_and_indent_event(event)
David Scherer7aced172000-08-15 01:13:23 +00001031 return "break"
1032 # We're in the last line; append a newline and submit it
1033 self.text.mark_set("insert", "end-1c")
1034 if self.reading:
1035 self.text.insert("insert", "\n")
1036 self.text.see("insert")
1037 else:
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001038 self.newline_and_indent_event(event)
David Scherer7aced172000-08-15 01:13:23 +00001039 self.text.tag_add("stdin", "iomark", "end-1c")
1040 self.text.update_idletasks()
1041 if self.reading:
1042 self.top.quit() # Break out of recursive mainloop() in raw_input()
1043 else:
1044 self.runit()
1045 return "break"
1046
1047 def recall(self, s):
1048 if self.history:
1049 self.history.recall(s)
1050
1051 def runit(self):
1052 line = self.text.get("iomark", "end-1c")
1053 # Strip off last newline and surrounding whitespace.
1054 # (To allow you to hit return twice to end a statement.)
1055 i = len(line)
1056 while i > 0 and line[i-1] in " \t":
1057 i = i-1
1058 if i > 0 and line[i-1] == "\n":
1059 i = i-1
1060 while i > 0 and line[i-1] in " \t":
1061 i = i-1
1062 line = line[:i]
1063 more = self.interp.runsource(line)
David Scherer7aced172000-08-15 01:13:23 +00001064
David Scherer7aced172000-08-15 01:13:23 +00001065 def open_stack_viewer(self, event=None):
Chui Tey5d2af632002-05-26 13:36:41 +00001066 if self.interp.rpcclt:
1067 return self.interp.remote_stack_viewer()
David Scherer7aced172000-08-15 01:13:23 +00001068 try:
1069 sys.last_traceback
1070 except:
1071 tkMessageBox.showerror("No stack trace",
1072 "There is no stack trace yet.\n"
1073 "(sys.last_traceback is not defined)",
1074 master=self.text)
1075 return
1076 from StackViewer import StackBrowser
1077 sv = StackBrowser(self.root, self.flist)
1078
Kurt B. Kaiser1061e722003-01-04 01:43:53 +00001079 def view_restart_mark(self, event=None):
1080 self.text.see("iomark")
1081 self.text.see("restart")
1082
1083 def restart_shell(self, event=None):
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +00001084 self.interp.restart_subprocess()
Kurt B. Kaiser1061e722003-01-04 01:43:53 +00001085
David Scherer7aced172000-08-15 01:13:23 +00001086 def showprompt(self):
1087 self.resetoutput()
1088 try:
1089 s = str(sys.ps1)
1090 except:
1091 s = ""
1092 self.console.write(s)
1093 self.text.mark_set("insert", "end-1c")
Chui Tey5d2af632002-05-26 13:36:41 +00001094 self.set_line_and_column()
Kurt B. Kaiserdc1e7092002-07-11 04:33:41 +00001095 self.io.reset_undo()
David Scherer7aced172000-08-15 01:13:23 +00001096
1097 def resetoutput(self):
1098 source = self.text.get("iomark", "end-1c")
1099 if self.history:
1100 self.history.history_store(source)
1101 if self.text.get("end-2c") != "\n":
1102 self.text.insert("end-1c", "\n")
1103 self.text.mark_set("iomark", "end-1c")
Chui Tey5d2af632002-05-26 13:36:41 +00001104 self.set_line_and_column()
David Scherer7aced172000-08-15 01:13:23 +00001105 sys.stdout.softspace = 0
1106
1107 def write(self, s, tags=()):
Kurt B. Kaiser003091c2003-02-17 18:57:16 +00001108 try:
1109 self.text.mark_gravity("iomark", "right")
1110 OutputWindow.write(self, s, tags, "iomark")
1111 self.text.mark_gravity("iomark", "left")
1112 except:
1113 pass
David Scherer7aced172000-08-15 01:13:23 +00001114 if self.canceled:
1115 self.canceled = 0
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +00001116 if not use_subprocess:
1117 raise KeyboardInterrupt
David Scherer7aced172000-08-15 01:13:23 +00001118
1119class PseudoFile:
1120
Martin v. Löwisbcc651a2003-06-22 07:52:56 +00001121 def __init__(self, shell, tags, encoding=None):
David Scherer7aced172000-08-15 01:13:23 +00001122 self.shell = shell
1123 self.tags = tags
Chui Tey5d2af632002-05-26 13:36:41 +00001124 self.softspace = 0
Martin v. Löwisbcc651a2003-06-22 07:52:56 +00001125 self.encoding = encoding
David Scherer7aced172000-08-15 01:13:23 +00001126
1127 def write(self, s):
1128 self.shell.write(s, self.tags)
1129
1130 def writelines(self, l):
1131 map(self.write, l)
1132
1133 def flush(self):
1134 pass
1135
1136 def isatty(self):
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +00001137 return True
David Scherer7aced172000-08-15 01:13:23 +00001138
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001139
David Scherer7aced172000-08-15 01:13:23 +00001140usage_msg = """\
David Scherer7aced172000-08-15 01:13:23 +00001141
Kurt B. Kaiser11659ad2003-05-15 23:23:21 +00001142USAGE: idle [-deins] [-t title] [file]*
1143 idle [-dns] [-t title] (-c cmd | -r file) [arg]*
1144 idle [-dns] [-t title] - [arg]*
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001145
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001146 -h print this help message and exit
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001147 -n run IDLE without a subprocess (see Help/IDLE Help for details)
David Scherer7aced172000-08-15 01:13:23 +00001148
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001149The following options will override the IDLE 'settings' configuration:
Kurt B. Kaiser96d88422001-07-17 04:59:01 +00001150
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001151 -e open an edit window
1152 -i open a shell window
1153
1154The following options imply -i and will open a shell:
1155
1156 -c cmd run the command in a shell, or
1157 -r file run script from file
1158
1159 -d enable the debugger
1160 -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1161 -t title set title of shell window
1162
1163A default edit window will be bypassed when -c, -r, or - are used.
1164
1165[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1166
1167Examples:
1168
1169idle
1170 Open an edit window or shell depending on IDLE's configuration.
1171
1172idle foo.py foobar.py
1173 Edit the files, also open a shell if configured to start with shell.
1174
1175idle -est "Baz" foo.py
1176 Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1177 window with the title "Baz".
1178
1179idle -c "import sys; print sys.argv" "foo"
1180 Open a shell window and run the command, passing "-c" in sys.argv[0]
1181 and "foo" in sys.argv[1].
1182
1183idle -d -s -r foo.py "Hello World"
1184 Open a shell window, run a startup script, enable the debugger, and
1185 run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1186 sys.argv[1].
1187
1188echo "import sys; print sys.argv" | idle - "foobar"
1189 Open a shell window, run the script piped in, passing '' in sys.argv[0]
1190 and "foobar" in sys.argv[1].
David Scherer7aced172000-08-15 01:13:23 +00001191"""
1192
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001193def main():
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001194 global flist, root, use_subprocess
David Scherer7aced172000-08-15 01:13:23 +00001195
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001196 use_subprocess = True
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001197 enable_shell = False
1198 enable_edit = False
1199 debug = False
1200 cmd = None
1201 script = None
1202 startup = False
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001203 try:
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001204 sys.ps1
1205 except AttributeError:
1206 sys.ps1 = '>>> '
1207 try:
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001208 opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001209 except getopt.error, msg:
1210 sys.stderr.write("Error: %s\n" % str(msg))
1211 sys.stderr.write(usage_msg)
1212 sys.exit(2)
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001213 for o, a in opts:
1214 if o == '-c':
1215 cmd = a
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001216 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001217 if o == '-d':
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001218 debug = True
1219 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001220 if o == '-e':
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001221 enable_edit = True
1222 if o == '-h':
1223 sys.stdout.write(usage_msg)
1224 sys.exit()
1225 if o == '-i':
1226 enable_shell = True
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001227 if o == '-n':
1228 use_subprocess = False
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001229 if o == '-r':
1230 script = a
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001231 if os.path.isfile(script):
1232 pass
1233 else:
1234 print "No script file: ", script
1235 sys.exit()
1236 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001237 if o == '-s':
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001238 startup = True
1239 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001240 if o == '-t':
1241 PyShell.shell_title = a
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001242 enable_shell = True
1243 if args and args[0] == '-':
1244 cmd = sys.stdin.read()
1245 enable_shell = True
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001246 # process sys.argv and sys.path:
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001247 for i in range(len(sys.path)):
1248 sys.path[i] = os.path.abspath(sys.path[i])
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001249 if args and args[0] == '-':
1250 sys.argv = [''] + args[1:]
1251 elif cmd:
1252 sys.argv = ['-c'] + args
1253 elif script:
1254 sys.argv = [script] + args
1255 elif args:
1256 enable_edit = True
1257 pathx = []
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001258 for filename in args:
1259 pathx.append(os.path.dirname(filename))
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001260 for dir in pathx:
1261 dir = os.path.abspath(dir)
1262 if not dir in sys.path:
1263 sys.path.insert(0, dir)
Kurt B. Kaiserff002b92002-12-21 21:39:11 +00001264 else:
1265 dir = os.getcwd()
1266 if not dir in sys.path:
1267 sys.path.insert(0, dir)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001268 # check the IDLE settings configuration (but command line overrides)
1269 edit_start = idleConf.GetOption('main', 'General',
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001270 'editor-on-startup', type='bool')
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001271 enable_edit = enable_edit or edit_start
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001272 enable_shell = enable_shell or not edit_start
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001273 # start editor and/or shell windows:
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001274 root = Tk(className="Idle")
1275 fixwordbreaks(root)
1276 root.withdraw()
1277 flist = PyShellFileList(root)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001278 if enable_edit:
1279 if not (cmd or script):
1280 for filename in args:
1281 flist.open(filename)
1282 if not args:
1283 flist.new()
1284 if enable_shell:
1285 flist.open_shell()
1286 elif enable_shell:
1287 flist.pyshell = PyShell(flist)
1288 flist.pyshell.begin()
1289 shell = flist.pyshell
1290 # handle remaining options:
1291 if debug:
1292 shell.open_debugger()
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001293 if startup:
1294 filename = os.environ.get("IDLESTARTUP") or \
1295 os.environ.get("PYTHONSTARTUP")
1296 if filename and os.path.isfile(filename):
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001297 shell.interp.execfile(filename)
1298 if cmd or script:
1299 shell.interp.runcommand("""if 1:
1300 import sys as _sys
1301 _sys.argv = %s
1302 del _sys
1303 \n""" % `sys.argv`)
1304 if cmd:
1305 shell.interp.execsource(cmd)
1306 elif script:
Kurt B. Kaiser11659ad2003-05-15 23:23:21 +00001307 shell.interp.prepend_syspath(script)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001308 shell.interp.execfile(script)
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001309 root.mainloop()
1310 root.destroy()
1311
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001312
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001313def display_port_binding_error():
1314 print """\
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001315\nIDLE cannot run.
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001316
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001317IDLE needs to use a specific TCP/IP port (8833) in order to communicate with
1318its Python execution server. IDLE is unable to bind to this port, and so
1319cannot start. Here are some possible causes of this problem:
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001320
1321 1. TCP/IP networking is not installed or not working on this computer
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001322 2. Another program (another IDLE?) is running that uses this port
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001323 3. Personal firewall software is preventing IDLE from using this port
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001324
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001325Run IDLE with the -n command line switch to start without a subprocess
1326and refer to Help/IDLE Help "Running without a subprocess" for further
1327details.
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001328"""
David Scherer7aced172000-08-15 01:13:23 +00001329
1330if __name__ == "__main__":
Kurt B. Kaiser9e8b8282003-06-15 17:38:45 +00001331 sys.modules['PyShell'] = sys.modules['__main__']
David Scherer7aced172000-08-15 01:13:23 +00001332 main()