blob: 81ef88e8af7e59320ee2bcea1f29f650d39439e2 [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
19from Tkinter import *
20import tkMessageBox
21
22from EditorWindow import EditorWindow, fixwordbreaks
23from FileList import FileList
24from ColorDelegator import ColorDelegator
25from UndoDelegator import UndoDelegator
Kurt B. Kaiser969de452002-06-12 03:28:57 +000026from OutputWindow import OutputWindow
Steven M. Gava99300612001-11-04 07:03:08 +000027from configHandler import idleConf
David Scherer7aced172000-08-15 01:13:23 +000028import idlever
29
Chui Tey5d2af632002-05-26 13:36:41 +000030import rpc
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +000031import Debugger
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000032import RemoteDebugger
Chui Tey5d2af632002-05-26 13:36:41 +000033
Kurt B. Kaiserb9764192002-09-23 04:10:37 +000034IDENTCHARS = string.ascii_letters + string.digits + "_"
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +000035LOCALHOST = '127.0.0.1'
Kurt B. Kaiserb9764192002-09-23 04:10:37 +000036
Kurt B. Kaisera00050f2003-05-08 20:26:55 +000037try:
38 from signal import SIGTERM
39except ImportError:
40 SIGTERM = 15
41
Chui Tey5d2af632002-05-26 13:36:41 +000042# Change warnings module to write to sys.__stderr__
43try:
44 import warnings
45except ImportError:
46 pass
47else:
48 def idle_showwarning(message, category, filename, lineno):
49 file = sys.__stderr__
50 file.write(warnings.formatwarning(message, category, filename, lineno))
51 warnings.showwarning = idle_showwarning
52
Kurt B. Kaiser81885592002-11-29 22:10:53 +000053def extended_linecache_checkcache(orig_checkcache=linecache.checkcache):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000054 """Extend linecache.checkcache to preserve the <pyshell#...> entries
55
Kurt B. Kaiser81885592002-11-29 22:10:53 +000056 Rather than repeating the linecache code, patch it to save the pyshell#
57 entries, call the original linecache.checkcache(), and then restore the
58 saved entries. Assigning the orig_checkcache keyword arg freezes its value
59 at definition time to the (original) method linecache.checkcache(), i.e.
60 makes orig_checkcache lexical.
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000061
62 """
David Scherer7aced172000-08-15 01:13:23 +000063 cache = linecache.cache
64 save = {}
65 for filename in cache.keys():
66 if filename[:1] + filename[-1:] == '<>':
67 save[filename] = cache[filename]
68 orig_checkcache()
69 cache.update(save)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000070
Kurt B. Kaiser81885592002-11-29 22:10:53 +000071# Patch linecache.checkcache():
72linecache.checkcache = extended_linecache_checkcache
David Scherer7aced172000-08-15 01:13:23 +000073
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000074
David Scherer7aced172000-08-15 01:13:23 +000075class PyShellEditorWindow(EditorWindow):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000076 "Regular text edit window when a shell is present"
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000077
David Scherer7aced172000-08-15 01:13:23 +000078 def __init__(self, *args):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000079 self.breakpoints = []
Raymond Hettinger931237e2003-07-09 18:48:24 +000080 EditorWindow.__init__(self, *args)
David Scherer7aced172000-08-15 01:13:23 +000081 self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000082 self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
David Scherer7aced172000-08-15 01:13:23 +000083 self.text.bind("<<open-python-shell>>", self.flist.open_shell)
84
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +000085 self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
86 'breakpoints.lst')
Chui Teya2adb0f2002-11-04 22:14:54 +000087 # whenever a file is changed, restore breakpoints
88 if self.io.filename: self.restore_file_breaks()
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +000089 def filename_changed_hook(old_hook=self.io.filename_change_hook,
90 self=self):
Chui Teya2adb0f2002-11-04 22:14:54 +000091 self.restore_file_breaks()
92 old_hook()
93 self.io.set_filename_change_hook(filename_changed_hook)
94
Kurt B. Kaiser45186c42002-10-23 04:48:08 +000095 rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
96 ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
David Scherer7aced172000-08-15 01:13:23 +000097
Chui Teya2adb0f2002-11-04 22:14:54 +000098 def set_breakpoint(self, lineno):
99 text = self.text
100 filename = self.io.filename
101 text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
102 try:
103 i = self.breakpoints.index(lineno)
104 except ValueError: # only add if missing, i.e. do once
105 self.breakpoints.append(lineno)
106 try: # update the subprocess debugger
107 debug = self.flist.pyshell.interp.debugger
108 debug.set_breakpoint_here(filename, lineno)
109 except: # but debugger may not be active right now....
110 pass
111
David Scherer7aced172000-08-15 01:13:23 +0000112 def set_breakpoint_here(self, event=None):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000113 text = self.text
114 filename = self.io.filename
115 if not filename:
116 text.bell()
David Scherer7aced172000-08-15 01:13:23 +0000117 return
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000118 lineno = int(float(text.index("insert")))
Chui Teya2adb0f2002-11-04 22:14:54 +0000119 self.set_breakpoint(lineno)
David Scherer7aced172000-08-15 01:13:23 +0000120
Kurt B. Kaiser669f4c32002-06-20 04:01:47 +0000121 def clear_breakpoint_here(self, event=None):
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000122 text = self.text
123 filename = self.io.filename
124 if not filename:
125 text.bell()
Kurt B. Kaiser669f4c32002-06-20 04:01:47 +0000126 return
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000127 lineno = int(float(text.index("insert")))
128 try:
129 self.breakpoints.remove(lineno)
130 except:
131 pass
132 text.tag_remove("BREAK", "insert linestart",\
133 "insert lineend +1char")
134 try:
135 debug = self.flist.pyshell.interp.debugger
136 debug.clear_breakpoint_here(filename, lineno)
137 except:
138 pass
139
140 def clear_file_breaks(self):
141 if self.breakpoints:
142 text = self.text
143 filename = self.io.filename
144 if not filename:
145 text.bell()
146 return
147 self.breakpoints = []
148 text.tag_remove("BREAK", "1.0", END)
149 try:
150 debug = self.flist.pyshell.interp.debugger
151 debug.clear_file_breaks(filename)
152 except:
153 pass
154
Chui Teya2adb0f2002-11-04 22:14:54 +0000155 def store_file_breaks(self):
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000156 "Save breakpoints when file is saved"
157 # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
158 # be run. The breaks are saved at that time. If we introduce
159 # a temporary file save feature the save breaks functionality
160 # needs to be re-verified, since the breaks at the time the
161 # temp file is created may differ from the breaks at the last
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000162 # permanent save of the file. Currently, a break introduced
163 # after a save will be effective, but not persistent.
164 # This is necessary to keep the saved breaks synched with the
165 # saved file.
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000166 #
167 # Breakpoints are set as tagged ranges in the text. Certain
168 # kinds of edits cause these ranges to be deleted: Inserting
169 # or deleting a line just before a breakpoint, and certain
170 # deletions prior to a breakpoint. These issues need to be
171 # investigated and understood. It's not clear if they are
172 # Tk issues or IDLE issues, or whether they can actually
173 # be fixed. Since a modified file has to be saved before it is
174 # run, and since self.breakpoints (from which the subprocess
175 # debugger is loaded) is updated during the save, the visible
176 # breaks stay synched with the subprocess even if one of these
177 # unexpected breakpoint deletions occurs.
178 breaks = self.breakpoints
179 filename = self.io.filename
Chui Teya2adb0f2002-11-04 22:14:54 +0000180 try:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000181 lines = open(self.breakpointPath,"r").readlines()
Chui Teya2adb0f2002-11-04 22:14:54 +0000182 except IOError:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000183 lines = []
184 new_file = open(self.breakpointPath,"w")
Chui Teya2adb0f2002-11-04 22:14:54 +0000185 for line in lines:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000186 if not line.startswith(filename + '='):
Chui Teya2adb0f2002-11-04 22:14:54 +0000187 new_file.write(line)
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000188 self.update_breakpoints()
189 breaks = self.breakpoints
190 if breaks:
191 new_file.write(filename + '=' + str(breaks) + '\n')
Chui Teya2adb0f2002-11-04 22:14:54 +0000192 new_file.close()
193
194 def restore_file_breaks(self):
195 self.text.update() # this enables setting "BREAK" tags to be visible
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000196 filename = self.io.filename
197 if filename is None:
198 return
Chui Tey69371d62002-11-04 23:39:45 +0000199 if os.path.isfile(self.breakpointPath):
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000200 lines = open(self.breakpointPath,"r").readlines()
Chui Tey69371d62002-11-04 23:39:45 +0000201 for line in lines:
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000202 if line.startswith(filename + '='):
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000203 breakpoint_linenumbers = eval(line[len(filename)+1:])
Chui Tey69371d62002-11-04 23:39:45 +0000204 for breakpoint_linenumber in breakpoint_linenumbers:
205 self.set_breakpoint(breakpoint_linenumber)
Chui Teya2adb0f2002-11-04 22:14:54 +0000206
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000207 def update_breakpoints(self):
208 "Retrieves all the breakpoints in the current window"
Chui Teya2adb0f2002-11-04 22:14:54 +0000209 text = self.text
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000210 ranges = text.tag_ranges("BREAK")
211 linenumber_list = self.ranges_to_linenumbers(ranges)
212 self.breakpoints = linenumber_list
213
214 def ranges_to_linenumbers(self, ranges):
215 lines = []
216 for index in range(0, len(ranges), 2):
217 lineno = int(float(ranges[index]))
218 end = int(float(ranges[index+1]))
219 while lineno < end:
220 lines.append(lineno)
221 lineno += 1
222 return lines
223
Kurt B. Kaiser11220fa2002-12-24 00:57:22 +0000224# XXX 13 Dec 2002 KBK Not used currently
Kurt B. Kaiserbfed3462002-12-14 04:38:51 +0000225# def saved_change_hook(self):
226# "Extend base method - clear breaks if module is modified"
227# if not self.get_saved():
228# self.clear_file_breaks()
229# EditorWindow.saved_change_hook(self)
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000230
231 def _close(self):
232 "Extend base method - clear breaks when module is closed"
233 self.clear_file_breaks()
234 EditorWindow._close(self)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000235
David Scherer7aced172000-08-15 01:13:23 +0000236
237class PyShellFileList(FileList):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000238 "Extend base class: file list when a shell is present"
David Scherer7aced172000-08-15 01:13:23 +0000239
240 EditorWindow = PyShellEditorWindow
241
242 pyshell = None
243
244 def open_shell(self, event=None):
245 if self.pyshell:
246 self.pyshell.wakeup()
247 else:
248 self.pyshell = PyShell(self)
249 self.pyshell.begin()
250 return self.pyshell
251
252
253class ModifiedColorDelegator(ColorDelegator):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000254 "Extend base class: colorizer for the shell window itself"
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000255
Steven M. Gavab77d3432002-03-02 07:16:21 +0000256 def __init__(self):
257 ColorDelegator.__init__(self)
258 self.LoadTagDefs()
David Scherer7aced172000-08-15 01:13:23 +0000259
260 def recolorize_main(self):
261 self.tag_remove("TODO", "1.0", "iomark")
262 self.tag_add("SYNC", "1.0", "iomark")
263 ColorDelegator.recolorize_main(self)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000264
Steven M. Gavab77d3432002-03-02 07:16:21 +0000265 def LoadTagDefs(self):
266 ColorDelegator.LoadTagDefs(self)
267 theme = idleConf.GetOption('main','Theme','name')
268 self.tagdefs.update({
269 "stdin": {'background':None,'foreground':None},
270 "stdout": idleConf.GetHighlight(theme, "stdout"),
271 "stderr": idleConf.GetHighlight(theme, "stderr"),
272 "console": idleConf.GetHighlight(theme, "console"),
Steven M. Gavab77d3432002-03-02 07:16:21 +0000273 None: idleConf.GetHighlight(theme, "normal"),
274 })
David Scherer7aced172000-08-15 01:13:23 +0000275
David Scherer7aced172000-08-15 01:13:23 +0000276class ModifiedUndoDelegator(UndoDelegator):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000277 "Extend base class: forbid insert/delete before the I/O mark"
David Scherer7aced172000-08-15 01:13:23 +0000278
279 def insert(self, index, chars, tags=None):
280 try:
281 if self.delegate.compare(index, "<", "iomark"):
282 self.delegate.bell()
283 return
284 except TclError:
285 pass
286 UndoDelegator.insert(self, index, chars, tags)
287
288 def delete(self, index1, index2=None):
289 try:
290 if self.delegate.compare(index1, "<", "iomark"):
291 self.delegate.bell()
292 return
293 except TclError:
294 pass
295 UndoDelegator.delete(self, index1, index2)
296
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000297
298class MyRPCClient(rpc.RPCClient):
299
300 def handle_EOF(self):
301 "Override the base class - just re-raise EOFError"
302 raise EOFError
303
Kurt B. Kaiser8d1f11b2003-05-26 22:20:34 +0000304
David Scherer7aced172000-08-15 01:13:23 +0000305class ModifiedInterpreter(InteractiveInterpreter):
306
307 def __init__(self, tkconsole):
308 self.tkconsole = tkconsole
309 locals = sys.modules['__main__'].__dict__
310 InteractiveInterpreter.__init__(self, locals=locals)
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000311 self.save_warnings_filters = None
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000312 self.restarting = False
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000313 self.subprocess_arglist = self.build_subprocess_arglist()
David Scherer7aced172000-08-15 01:13:23 +0000314
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000315 port = 8833
Chui Tey5d2af632002-05-26 13:36:41 +0000316 rpcclt = None
317 rpcpid = None
318
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000319 def spawn_subprocess(self):
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000320 args = self.subprocess_arglist
Kurt B. Kaiserb7855182003-08-14 14:54:28 +0000321 self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000322
Tony Lowndsf53dec22002-12-20 04:24:43 +0000323 def build_subprocess_arglist(self):
Tony Lownds2398d572003-05-13 15:28:21 +0000324 w = ['-W' + s for s in sys.warnoptions]
325 # Maybe IDLE is installed and is being accessed via sys.path,
326 # or maybe it's not installed and the idle.py script is being
327 # run from the IDLE source directory.
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000328 del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
329 default=False, type='bool')
Tony Lownds2398d572003-05-13 15:28:21 +0000330 if __name__ == 'idlelib.PyShell':
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000331 command = "__import__('idlelib.run').run.main(" + `del_exitf` +")"
Tony Lowndsf2324b92002-09-29 00:34:10 +0000332 else:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000333 command = "__import__('run').main(" + `del_exitf` + ")"
Kurt B. Kaiserb7855182003-08-14 14:54:28 +0000334 if sys.platform[:3] == 'win' and ' ' in sys.executable:
335 # handle embedded space in path by quoting the argument
336 decorated_exec = '"%s"' % sys.executable
337 else:
338 decorated_exec = sys.executable
339 return [decorated_exec] + w + ["-c", command, str(self.port)]
Tony Lowndsf2324b92002-09-29 00:34:10 +0000340
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000341 def start_subprocess(self):
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +0000342 addr = (LOCALHOST, self.port)
Kurt B. Kaiser8dcdb772002-08-05 03:52:10 +0000343 # Idle starts listening for connection on localhost
Kurt B. Kaiser5db48432003-05-15 03:40:51 +0000344 for i in range(3):
Chui Tey5d2af632002-05-26 13:36:41 +0000345 time.sleep(i)
346 try:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000347 self.rpcclt = MyRPCClient(addr)
Chui Tey5d2af632002-05-26 13:36:41 +0000348 break
349 except socket.error, err:
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000350 print>>sys.__stderr__,"IDLE socket error: " + err[1]\
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000351 + ", retrying..."
Chui Tey5d2af632002-05-26 13:36:41 +0000352 else:
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000353 display_port_binding_error()
Kurt B. Kaisera2a3cb22002-12-24 03:33:12 +0000354 sys.exit()
Kurt B. Kaiser5db48432003-05-15 03:40:51 +0000355 self.spawn_subprocess()
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000356 # Accept the connection from the Python execution server
357 self.rpcclt.accept()
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000358 self.rpcclt.register("stdin", self.tkconsole)
359 self.rpcclt.register("stdout", self.tkconsole.stdout)
360 self.rpcclt.register("stderr", self.tkconsole.stderr)
Chui Tey5d2af632002-05-26 13:36:41 +0000361 self.rpcclt.register("flist", self.tkconsole.flist)
Kurt B. Kaiser8cd0def2003-01-31 05:06:43 +0000362 self.rpcclt.register("linecache", linecache)
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000363 self.rpcclt.register("interp", self)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000364 self.transfer_path()
Chui Tey5d2af632002-05-26 13:36:41 +0000365 self.poll_subprocess()
366
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000367 def restart_subprocess(self):
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000368 if self.restarting:
369 return
370 self.restarting = True
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000371 # close only the subprocess debugger
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000372 debug = self.getdebugger()
373 if debug:
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000374 try:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000375 # Only close subprocess debugger, don't unregister gui_adap!
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000376 RemoteDebugger.close_subprocess_debugger(self.rpcclt)
377 except:
378 pass
379 # Kill subprocess, spawn a new one, accept connection.
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000380 self.rpcclt.close()
381 self.unix_terminate()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000382 console = self.tkconsole
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000383 was_executing = console.executing
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000384 console.executing = False
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000385 self.spawn_subprocess()
386 self.rpcclt.accept()
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000387 self.transfer_path()
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000388 # annotate restart in shell window and mark it
Kurt B. Kaiser4cc5ef52003-01-22 00:23:23 +0000389 console.text.delete("iomark", "end-1c")
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000390 if was_executing:
391 console.write('\n')
392 console.showprompt()
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000393 halfbar = ((int(console.width) - 16) // 2) * '='
394 console.write(halfbar + ' RESTART ' + halfbar)
395 console.text.mark_set("restart", "end-1c")
396 console.text.mark_gravity("restart", "left")
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000397 console.showprompt()
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000398 # restart subprocess debugger
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000399 if debug:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000400 # Restarted debugger connects to current instance of debug GUI
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000401 gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000402 # reload remote debugger breakpoints for all PyShellEditWindows
403 debug.load_breakpoints()
Kurt B. Kaiser6f805942003-05-24 21:12:46 +0000404 self.restarting = False
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000405
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000406 def __request_interrupt(self):
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000407 self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000408
409 def interrupt_subprocess(self):
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000410 threading.Thread(target=self.__request_interrupt).start()
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000411
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000412 def kill_subprocess(self):
413 self.rpcclt.close()
414 self.unix_terminate()
415 self.tkconsole.executing = False
416 self.rpcclt = None
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000417
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000418 def unix_terminate(self):
419 "UNIX: make sure subprocess is terminated and collect status"
420 if hasattr(os, 'kill'):
421 try:
422 os.kill(self.rpcpid, SIGTERM)
423 except OSError:
424 # process already terminated:
425 return
426 else:
427 try:
428 os.waitpid(self.rpcpid, 0)
429 except OSError:
430 return
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000431
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000432 def transfer_path(self):
433 self.runcommand("""if 1:
434 import sys as _sys
435 _sys.path = %s
436 del _sys
Kurt B. Kaiserb2487332003-03-04 04:03:45 +0000437 _msg = 'Use File/Exit or your end-of-file key to quit IDLE'
438 __builtins__.quit = __builtins__.exit = _msg
439 del _msg
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000440 \n""" % `sys.path`)
441
Chui Tey5d2af632002-05-26 13:36:41 +0000442 active_seq = None
443
444 def poll_subprocess(self):
445 clt = self.rpcclt
446 if clt is None:
447 return
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000448 try:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000449 response = clt.pollresponse(self.active_seq, wait=0.05)
450 except (EOFError, IOError, KeyboardInterrupt):
451 # lost connection or subprocess terminated itself, restart
452 # [the KBI is from rpc.SocketIO.handle_EOF()]
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000453 if self.tkconsole.closing:
454 return
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000455 response = None
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000456 self.restart_subprocess()
Chui Tey5d2af632002-05-26 13:36:41 +0000457 if response:
458 self.tkconsole.resetoutput()
459 self.active_seq = None
460 how, what = response
Kurt B. Kaiserbc286132003-01-25 21:33:40 +0000461 console = self.tkconsole.console
Chui Tey5d2af632002-05-26 13:36:41 +0000462 if how == "OK":
463 if what is not None:
Kurt B. Kaiserbc286132003-01-25 21:33:40 +0000464 print >>console, `what`
Chui Tey5d2af632002-05-26 13:36:41 +0000465 elif how == "EXCEPTION":
Chui Tey5d2af632002-05-26 13:36:41 +0000466 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
467 self.remote_stack_viewer()
468 elif how == "ERROR":
Kurt B. Kaiser0930c432002-12-06 21:45:24 +0000469 errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
470 print >>sys.__stderr__, errmsg, what
Kurt B. Kaiserbc286132003-01-25 21:33:40 +0000471 print >>console, errmsg, what
472 # we received a response to the currently active seq number:
Chui Tey5d2af632002-05-26 13:36:41 +0000473 self.tkconsole.endexecuting()
Kurt B. Kaiser88957d82003-05-19 23:11:51 +0000474 # Reschedule myself
475 if not self.tkconsole.closing:
476 self.tkconsole.text.after(self.tkconsole.pollinterval,
477 self.poll_subprocess)
Chui Tey5d2af632002-05-26 13:36:41 +0000478
Kurt B. Kaiser45186c42002-10-23 04:48:08 +0000479 debugger = None
480
481 def setdebugger(self, debugger):
482 self.debugger = debugger
483
484 def getdebugger(self):
485 return self.debugger
486
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000487 def open_remote_stack_viewer(self):
488 """Initiate the remote stack viewer from a separate thread.
489
490 This method is called from the subprocess, and by returning from this
491 method we allow the subprocess to unblock. After a bit the shell
492 requests the subprocess to open the remote stack viewer which returns a
493 static object looking at the last exceptiopn. It is queried through
494 the RPC mechanism.
495
496 """
497 self.tkconsole.text.after(300, self.remote_stack_viewer)
498 return
499
Chui Tey5d2af632002-05-26 13:36:41 +0000500 def remote_stack_viewer(self):
501 import RemoteObjectBrowser
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000502 oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
Chui Tey5d2af632002-05-26 13:36:41 +0000503 if oid is None:
504 self.tkconsole.root.bell()
505 return
506 item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
507 from TreeWidget import ScrolledCanvas, TreeNode
508 top = Toplevel(self.tkconsole.root)
509 sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
510 sc.frame.pack(expand=1, fill="both")
511 node = TreeNode(sc.canvas, None, item)
512 node.expand()
513 # XXX Should GC the remote tree when closing the window
514
David Scherer7aced172000-08-15 01:13:23 +0000515 gid = 0
516
517 def execsource(self, source):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000518 "Like runsource() but assumes complete exec source"
David Scherer7aced172000-08-15 01:13:23 +0000519 filename = self.stuffsource(source)
520 self.execfile(filename, source)
521
522 def execfile(self, filename, source=None):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000523 "Execute an existing file"
David Scherer7aced172000-08-15 01:13:23 +0000524 if source is None:
525 source = open(filename, "r").read()
526 try:
527 code = compile(source, filename, "exec")
528 except (OverflowError, SyntaxError):
529 self.tkconsole.resetoutput()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000530 tkerr = self.tkconsole.stderr
531 print>>tkerr, '*** Error in script or command!\n'
532 print>>tkerr, 'Traceback (most recent call last):'
David Scherer7aced172000-08-15 01:13:23 +0000533 InteractiveInterpreter.showsyntaxerror(self, filename)
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +0000534 self.tkconsole.showprompt()
David Scherer7aced172000-08-15 01:13:23 +0000535 else:
536 self.runcode(code)
537
538 def runsource(self, source):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000539 "Extend base class method: Stuff the source in the line cache first"
David Scherer7aced172000-08-15 01:13:23 +0000540 filename = self.stuffsource(source)
541 self.more = 0
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000542 self.save_warnings_filters = warnings.filters[:]
543 warnings.filterwarnings(action="error", category=SyntaxWarning)
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000544 if isinstance(source, types.UnicodeType):
545 import IOBinding
546 try:
547 source = source.encode(IOBinding.encoding)
548 except UnicodeError:
549 self.tkconsole.resetoutput()
550 self.write("Unsupported characters in input")
551 return
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000552 try:
553 return InteractiveInterpreter.runsource(self, source, filename)
554 finally:
555 if self.save_warnings_filters is not None:
556 warnings.filters[:] = self.save_warnings_filters
557 self.save_warnings_filters = None
David Scherer7aced172000-08-15 01:13:23 +0000558
559 def stuffsource(self, source):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000560 "Stuff source in the filename cache"
David Scherer7aced172000-08-15 01:13:23 +0000561 filename = "<pyshell#%d>" % self.gid
562 self.gid = self.gid + 1
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000563 lines = source.split("\n")
David Scherer7aced172000-08-15 01:13:23 +0000564 linecache.cache[filename] = len(source)+1, 0, lines, filename
565 return filename
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000566
Kurt B. Kaiser11659ad2003-05-15 23:23:21 +0000567 def prepend_syspath(self, filename):
568 "Prepend sys.path with file's directory if not already included"
569 self.runcommand("""if 1:
570 _filename = %s
571 import sys as _sys
572 from os.path import dirname as _dirname
573 _dir = _dirname(_filename)
574 if not _dir in _sys.path:
575 _sys.path.insert(0, _dir)
576 del _filename, _sys, _dirname, _dir
577 \n""" % `filename`)
578
David Scherer7aced172000-08-15 01:13:23 +0000579 def showsyntaxerror(self, filename=None):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000580 """Extend base class method: Add Colorizing
581
582 Color the offending position instead of printing it and pointing at it
583 with a caret.
584
585 """
David Scherer7aced172000-08-15 01:13:23 +0000586 text = self.tkconsole.text
587 stuff = self.unpackerror()
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +0000588 if stuff:
589 msg, lineno, offset, line = stuff
590 if lineno == 1:
591 pos = "iomark + %d chars" % (offset-1)
592 else:
593 pos = "iomark linestart + %d lines + %d chars" % \
594 (lineno-1, offset-1)
595 text.tag_add("ERROR", pos)
596 text.see(pos)
597 char = text.get(pos)
598 if char and char in IDENTCHARS:
599 text.tag_add("ERROR", pos + " wordstart", pos)
600 self.tkconsole.resetoutput()
601 self.write("SyntaxError: %s\n" % str(msg))
602 else:
David Scherer7aced172000-08-15 01:13:23 +0000603 self.tkconsole.resetoutput()
604 InteractiveInterpreter.showsyntaxerror(self, filename)
Kurt B. Kaiser6e44cc22002-11-30 06:18:00 +0000605 self.tkconsole.showprompt()
David Scherer7aced172000-08-15 01:13:23 +0000606
607 def unpackerror(self):
608 type, value, tb = sys.exc_info()
609 ok = type is SyntaxError
610 if ok:
611 try:
612 msg, (dummy_filename, lineno, offset, line) = value
Kurt B. Kaiserbea57c62003-07-09 04:27:24 +0000613 if not offset:
614 offset = 0
David Scherer7aced172000-08-15 01:13:23 +0000615 except:
616 ok = 0
617 if ok:
618 return msg, lineno, offset, line
619 else:
620 return None
621
622 def showtraceback(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000623 "Extend base class method to reset output properly"
David Scherer7aced172000-08-15 01:13:23 +0000624 self.tkconsole.resetoutput()
625 self.checklinecache()
626 InteractiveInterpreter.showtraceback(self)
Chui Tey5d2af632002-05-26 13:36:41 +0000627 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
628 self.tkconsole.open_stack_viewer()
David Scherer7aced172000-08-15 01:13:23 +0000629
630 def checklinecache(self):
631 c = linecache.cache
632 for key in c.keys():
633 if key[:1] + key[-1:] != "<>":
634 del c[key]
635
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000636 def display_executing_dialog(self):
637 tkMessageBox.showerror(
638 "Already executing",
639 "The Python Shell window is already executing a command; "
640 "please wait until it is finished.",
641 master=self.tkconsole.text)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000642
Chui Tey5d2af632002-05-26 13:36:41 +0000643 def runcommand(self, code):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000644 "Run the code without invoking the debugger"
Chui Tey5d2af632002-05-26 13:36:41 +0000645 # The code better not raise an exception!
646 if self.tkconsole.executing:
Neal Norwitzf4c4f112002-11-30 18:49:10 +0000647 self.display_executing_dialog()
Chui Tey5d2af632002-05-26 13:36:41 +0000648 return 0
649 if self.rpcclt:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000650 self.rpcclt.remotequeue("exec", "runcode", (code,), {})
Chui Tey5d2af632002-05-26 13:36:41 +0000651 else:
652 exec code in self.locals
653 return 1
654
David Scherer7aced172000-08-15 01:13:23 +0000655 def runcode(self, code):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000656 "Override base class method"
Chui Tey5d2af632002-05-26 13:36:41 +0000657 if self.tkconsole.executing:
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000658 self.interp.restart_subprocess()
Chui Tey5d2af632002-05-26 13:36:41 +0000659 self.checklinecache()
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000660 if self.save_warnings_filters is not None:
661 warnings.filters[:] = self.save_warnings_filters
662 self.save_warnings_filters = None
David Scherer7aced172000-08-15 01:13:23 +0000663 debugger = self.debugger
664 try:
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000665 self.tkconsole.beginexecuting()
666 try:
667 if not debugger and self.rpcclt is not None:
668 self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
669 (code,), {})
670 elif debugger:
671 debugger.run(code, self.locals)
672 else:
673 exec code in self.locals
674 except SystemExit:
675 if tkMessageBox.askyesno(
676 "Exit?",
677 "Do you want to exit altogether?",
678 default="yes",
679 master=self.tkconsole.text):
680 raise
681 else:
682 self.showtraceback()
683 except:
David Scherer7aced172000-08-15 01:13:23 +0000684 self.showtraceback()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000685 finally:
686 if not use_subprocess:
687 self.tkconsole.endexecuting()
David Scherer7aced172000-08-15 01:13:23 +0000688
689 def write(self, s):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000690 "Override base class method"
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000691 self.tkconsole.stderr.write(s)
David Scherer7aced172000-08-15 01:13:23 +0000692
David Scherer7aced172000-08-15 01:13:23 +0000693class PyShell(OutputWindow):
694
695 shell_title = "Python Shell"
696
697 # Override classes
698 ColorDelegator = ModifiedColorDelegator
699 UndoDelegator = ModifiedUndoDelegator
700
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +0000701 # Override menus
Kurt B. Kaiserdc1e7092002-07-11 04:33:41 +0000702 menu_specs = [
703 ("file", "_File"),
704 ("edit", "_Edit"),
Kurt B. Kaiser4cc5ef52003-01-22 00:23:23 +0000705 ("debug", "_Debug"),
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000706 ("options", "_Options"),
Kurt B. Kaiserdc1e7092002-07-11 04:33:41 +0000707 ("windows", "_Windows"),
708 ("help", "_Help"),
709 ]
David Scherer7aced172000-08-15 01:13:23 +0000710
711 # New classes
712 from IdleHistory import History
713
714 def __init__(self, flist=None):
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000715 if use_subprocess:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000716 ms = self.menu_specs
717 if ms[2][0] != "shell":
718 ms.insert(2, ("shell", "_Shell"))
David Scherer7aced172000-08-15 01:13:23 +0000719 self.interp = ModifiedInterpreter(self)
720 if flist is None:
721 root = Tk()
722 fixwordbreaks(root)
723 root.withdraw()
724 flist = PyShellFileList(root)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000725 #
David Scherer7aced172000-08-15 01:13:23 +0000726 OutputWindow.__init__(self, flist, None, None)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000727 #
David Scherer7aced172000-08-15 01:13:23 +0000728 import __builtin__
729 __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000730 #
Kurt B. Kaiseree7afca2002-09-14 02:50:56 +0000731 self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000732 #
David Scherer7aced172000-08-15 01:13:23 +0000733 text = self.text
734 text.configure(wrap="char")
735 text.bind("<<newline-and-indent>>", self.enter_callback)
736 text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
737 text.bind("<<interrupt-execution>>", self.cancel_callback)
738 text.bind("<<beginning-of-line>>", self.home_callback)
739 text.bind("<<end-of-file>>", self.eof_callback)
740 text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
Kurt B. Kaiser57bfe5d2003-05-10 00:09:52 +0000741 text.bind("<<toggle-debugger>>", self.toggle_debugger)
David Scherer7aced172000-08-15 01:13:23 +0000742 text.bind("<<open-python-shell>>", self.flist.open_shell)
743 text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000744 if use_subprocess:
745 text.bind("<<view-restart>>", self.view_restart_mark)
746 text.bind("<<restart-shell>>", self.restart_shell)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000747 #
David Scherer7aced172000-08-15 01:13:23 +0000748 self.save_stdout = sys.stdout
749 self.save_stderr = sys.stderr
750 self.save_stdin = sys.stdin
Martin v. Löwisbcc651a2003-06-22 07:52:56 +0000751 import IOBinding
752 self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
753 self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
754 self.console = PseudoFile(self, "console", IOBinding.encoding)
Chui Tey5d2af632002-05-26 13:36:41 +0000755 if not use_subprocess:
756 sys.stdout = self.stdout
757 sys.stderr = self.stderr
758 sys.stdin = self
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000759 #
David Scherer7aced172000-08-15 01:13:23 +0000760 self.history = self.History(self.text)
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000761 #
Kurt B. Kaiser88957d82003-05-19 23:11:51 +0000762 self.pollinterval = 50 # millisec
Chui Tey5d2af632002-05-26 13:36:41 +0000763 if use_subprocess:
Kurt B. Kaiser63857a42002-09-05 02:31:20 +0000764 self.interp.start_subprocess()
Chui Tey5d2af632002-05-26 13:36:41 +0000765
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000766 reading = False
767 executing = False
768 canceled = False
769 endoffile = False
770 closing = False
David Scherer7aced172000-08-15 01:13:23 +0000771
772 def toggle_debugger(self, event=None):
773 if self.executing:
774 tkMessageBox.showerror("Don't debug now",
775 "You can only toggle the debugger when idle",
776 master=self.text)
777 self.set_debugger_indicator()
778 return "break"
779 else:
780 db = self.interp.getdebugger()
781 if db:
782 self.close_debugger()
783 else:
784 self.open_debugger()
785
786 def set_debugger_indicator(self):
787 db = self.interp.getdebugger()
788 self.setvar("<<toggle-debugger>>", not not db)
789
Kurt B. Kaiser1061e722003-01-04 01:43:53 +0000790 def toggle_jit_stack_viewer(self, event=None):
David Scherer7aced172000-08-15 01:13:23 +0000791 pass # All we need is the variable
792
793 def close_debugger(self):
794 db = self.interp.getdebugger()
795 if db:
796 self.interp.setdebugger(None)
797 db.close()
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000798 if self.interp.rpcclt:
799 RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
David Scherer7aced172000-08-15 01:13:23 +0000800 self.resetoutput()
801 self.console.write("[DEBUG OFF]\n")
802 sys.ps1 = ">>> "
803 self.showprompt()
804 self.set_debugger_indicator()
805
806 def open_debugger(self):
Chui Tey5d2af632002-05-26 13:36:41 +0000807 if self.interp.rpcclt:
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000808 dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
809 self)
810 else:
811 dbg_gui = Debugger.Debugger(self)
812 self.interp.setdebugger(dbg_gui)
813 dbg_gui.load_breakpoints()
Chui Tey5d2af632002-05-26 13:36:41 +0000814 sys.ps1 = "[DEBUG ON]\n>>> "
815 self.showprompt()
816 self.set_debugger_indicator()
817
David Scherer7aced172000-08-15 01:13:23 +0000818 def beginexecuting(self):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000819 "Helper for ModifiedInterpreter"
David Scherer7aced172000-08-15 01:13:23 +0000820 self.resetoutput()
821 self.executing = 1
David Scherer7aced172000-08-15 01:13:23 +0000822
823 def endexecuting(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000824 "Helper for ModifiedInterpreter"
David Scherer7aced172000-08-15 01:13:23 +0000825 self.executing = 0
826 self.canceled = 0
Chui Tey5d2af632002-05-26 13:36:41 +0000827 self.showprompt()
David Scherer7aced172000-08-15 01:13:23 +0000828
829 def close(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000830 "Extend EditorWindow.close()"
David Scherer7aced172000-08-15 01:13:23 +0000831 if self.executing:
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000832 response = tkMessageBox.askokcancel(
David Scherer7aced172000-08-15 01:13:23 +0000833 "Kill?",
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000834 "The program is still running!\n Do you want to kill it?",
David Scherer7aced172000-08-15 01:13:23 +0000835 default="ok",
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000836 parent=self.text)
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000837 if response == False:
David Scherer7aced172000-08-15 01:13:23 +0000838 return "cancel"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000839 self.closing = True
840 # Wait for poll_subprocess() rescheduling to stop
841 self.text.after(2 * self.pollinterval, self.close2)
Kurt B. Kaiser88957d82003-05-19 23:11:51 +0000842
843 def close2(self):
844 return EditorWindow.close(self)
David Scherer7aced172000-08-15 01:13:23 +0000845
846 def _close(self):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000847 "Extend EditorWindow._close(), shut down debugger and execution server"
David Scherer7aced172000-08-15 01:13:23 +0000848 self.close_debugger()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000849 if use_subprocess:
850 self.interp.kill_subprocess()
David Scherer7aced172000-08-15 01:13:23 +0000851 # Restore std streams
852 sys.stdout = self.save_stdout
853 sys.stderr = self.save_stderr
854 sys.stdin = self.save_stdin
855 # Break cycles
856 self.interp = None
857 self.console = None
David Scherer7aced172000-08-15 01:13:23 +0000858 self.flist.pyshell = None
859 self.history = None
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000860 EditorWindow._close(self)
David Scherer7aced172000-08-15 01:13:23 +0000861
862 def ispythonsource(self, filename):
Kurt B. Kaiser83118c62002-06-24 17:03:37 +0000863 "Override EditorWindow method: never remove the colorizer"
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000864 return True
David Scherer7aced172000-08-15 01:13:23 +0000865
866 def short_title(self):
867 return self.shell_title
868
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000869 COPYRIGHT = \
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +0000870 'Type "copyright", "credits" or "license()" for more information.'
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000871
Kurt B. Kaiser220fecf2003-07-27 03:24:19 +0000872 firewallmessage = """
873 ****************************************************************
874 Personal firewall software may warn about the connection IDLE
875 makes to its subprocess using this computer's internal loopback
876 interface. This connection is not visible on any external
877 interface and no data is sent to or received from the Internet.
878 ****************************************************************
879 """
880
David Scherer7aced172000-08-15 01:13:23 +0000881 def begin(self):
882 self.resetoutput()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000883 if use_subprocess:
884 nosub = ''
885 else:
886 nosub = "==== No Subprocess ===="
Kurt B. Kaiser220fecf2003-07-27 03:24:19 +0000887 self.write("Python %s on %s\n%s\n%s\nIDLE %s %s\n" %
Kurt B. Kaiser94bd7742001-07-14 00:13:28 +0000888 (sys.version, sys.platform, self.COPYRIGHT,
Kurt B. Kaiser220fecf2003-07-27 03:24:19 +0000889 self.firewallmessage, idlever.IDLE_VERSION, nosub))
David Scherer7aced172000-08-15 01:13:23 +0000890 self.showprompt()
891 import Tkinter
892 Tkinter._default_root = None
893
894 def interact(self):
895 self.begin()
896 self.top.mainloop()
897
898 def readline(self):
899 save = self.reading
900 try:
901 self.reading = 1
902 self.top.mainloop()
903 finally:
904 self.reading = save
905 line = self.text.get("iomark", "end-1c")
Martin v. Löwisbcc651a2003-06-22 07:52:56 +0000906 if isinstance(line, unicode):
907 import IOBinding
908 try:
909 line = line.encode(IOBinding.encoding)
910 except UnicodeError:
911 pass
David Scherer7aced172000-08-15 01:13:23 +0000912 self.resetoutput()
913 if self.canceled:
914 self.canceled = 0
915 raise KeyboardInterrupt
916 if self.endoffile:
917 self.endoffile = 0
918 return ""
919 return line
920
921 def isatty(self):
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +0000922 return True
David Scherer7aced172000-08-15 01:13:23 +0000923
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000924 def cancel_callback(self, event=None):
David Scherer7aced172000-08-15 01:13:23 +0000925 try:
926 if self.text.compare("sel.first", "!=", "sel.last"):
927 return # Active selection -- always use default binding
928 except:
929 pass
930 if not (self.executing or self.reading):
931 self.resetoutput()
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +0000932 self.interp.write("KeyboardInterrupt\n")
David Scherer7aced172000-08-15 01:13:23 +0000933 self.showprompt()
934 return "break"
935 self.endoffile = 0
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000936 self.canceled = 1
David Scherer7aced172000-08-15 01:13:23 +0000937 if self.reading:
938 self.top.quit()
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000939 elif (self.executing and self.interp.rpcclt):
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000940 if self.interp.getdebugger():
941 self.interp.restart_subprocess()
942 else:
943 self.interp.interrupt_subprocess()
David Scherer7aced172000-08-15 01:13:23 +0000944 return "break"
945
946 def eof_callback(self, event):
947 if self.executing and not self.reading:
948 return # Let the default binding (delete next char) take over
949 if not (self.text.compare("iomark", "==", "insert") and
950 self.text.compare("insert", "==", "end-1c")):
951 return # Let the default binding (delete next char) take over
952 if not self.executing:
David Scherer7aced172000-08-15 01:13:23 +0000953 self.resetoutput()
954 self.close()
955 else:
956 self.canceled = 0
957 self.endoffile = 1
958 self.top.quit()
959 return "break"
960
961 def home_callback(self, event):
962 if event.state != 0 and event.keysym == "Home":
963 return # <Modifier-Home>; fall back to class binding
964 if self.text.compare("iomark", "<=", "insert") and \
965 self.text.compare("insert linestart", "<=", "iomark"):
966 self.text.mark_set("insert", "iomark")
967 self.text.tag_remove("sel", "1.0", "end")
968 self.text.see("insert")
969 return "break"
970
971 def linefeed_callback(self, event):
972 # Insert a linefeed without entering anything (still autoindented)
973 if self.reading:
974 self.text.insert("insert", "\n")
975 self.text.see("insert")
976 else:
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +0000977 self.newline_and_indent_event(event)
David Scherer7aced172000-08-15 01:13:23 +0000978 return "break"
979
980 def enter_callback(self, event):
981 if self.executing and not self.reading:
982 return # Let the default binding (insert '\n') take over
983 # If some text is selected, recall the selection
984 # (but only if this before the I/O mark)
985 try:
986 sel = self.text.get("sel.first", "sel.last")
987 if sel:
988 if self.text.compare("sel.last", "<=", "iomark"):
989 self.recall(sel)
990 return "break"
991 except:
992 pass
993 # If we're strictly before the line containing iomark, recall
994 # the current line, less a leading prompt, less leading or
995 # trailing whitespace
996 if self.text.compare("insert", "<", "iomark linestart"):
997 # Check if there's a relevant stdin range -- if so, use it
998 prev = self.text.tag_prevrange("stdin", "insert")
999 if prev and self.text.compare("insert", "<", prev[1]):
1000 self.recall(self.text.get(prev[0], prev[1]))
1001 return "break"
1002 next = self.text.tag_nextrange("stdin", "insert")
1003 if next and self.text.compare("insert lineend", ">=", next[0]):
1004 self.recall(self.text.get(next[0], next[1]))
1005 return "break"
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001006 # No stdin mark -- just get the current line, less any prompt
1007 line = self.text.get("insert linestart", "insert lineend")
1008 last_line_of_prompt = sys.ps1.split('\n')[-1]
1009 if line.startswith(last_line_of_prompt):
1010 line = line[len(last_line_of_prompt):]
1011 self.recall(line)
David Scherer7aced172000-08-15 01:13:23 +00001012 return "break"
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001013 # If we're between the beginning of the line and the iomark, i.e.
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001014 # in the prompt area, move to the end of the prompt
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001015 if self.text.compare("insert", "<", "iomark"):
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001016 self.text.mark_set("insert", "iomark")
David Scherer7aced172000-08-15 01:13:23 +00001017 # If we're in the current input and there's only whitespace
1018 # beyond the cursor, erase that whitespace first
1019 s = self.text.get("insert", "end-1c")
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +00001020 if s and not s.strip():
David Scherer7aced172000-08-15 01:13:23 +00001021 self.text.delete("insert", "end-1c")
1022 # If we're in the current input before its last line,
1023 # insert a newline right at the insert point
1024 if self.text.compare("insert", "<", "end-1c linestart"):
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001025 self.newline_and_indent_event(event)
David Scherer7aced172000-08-15 01:13:23 +00001026 return "break"
1027 # We're in the last line; append a newline and submit it
1028 self.text.mark_set("insert", "end-1c")
1029 if self.reading:
1030 self.text.insert("insert", "\n")
1031 self.text.see("insert")
1032 else:
Kurt B. Kaiser822a77f2002-12-16 02:07:11 +00001033 self.newline_and_indent_event(event)
David Scherer7aced172000-08-15 01:13:23 +00001034 self.text.tag_add("stdin", "iomark", "end-1c")
1035 self.text.update_idletasks()
1036 if self.reading:
1037 self.top.quit() # Break out of recursive mainloop() in raw_input()
1038 else:
1039 self.runit()
1040 return "break"
1041
1042 def recall(self, s):
1043 if self.history:
1044 self.history.recall(s)
1045
1046 def runit(self):
1047 line = self.text.get("iomark", "end-1c")
1048 # Strip off last newline and surrounding whitespace.
1049 # (To allow you to hit return twice to end a statement.)
1050 i = len(line)
1051 while i > 0 and line[i-1] in " \t":
1052 i = i-1
1053 if i > 0 and line[i-1] == "\n":
1054 i = i-1
1055 while i > 0 and line[i-1] in " \t":
1056 i = i-1
1057 line = line[:i]
1058 more = self.interp.runsource(line)
David Scherer7aced172000-08-15 01:13:23 +00001059
David Scherer7aced172000-08-15 01:13:23 +00001060 def open_stack_viewer(self, event=None):
Chui Tey5d2af632002-05-26 13:36:41 +00001061 if self.interp.rpcclt:
1062 return self.interp.remote_stack_viewer()
David Scherer7aced172000-08-15 01:13:23 +00001063 try:
1064 sys.last_traceback
1065 except:
1066 tkMessageBox.showerror("No stack trace",
1067 "There is no stack trace yet.\n"
1068 "(sys.last_traceback is not defined)",
1069 master=self.text)
1070 return
1071 from StackViewer import StackBrowser
1072 sv = StackBrowser(self.root, self.flist)
1073
Kurt B. Kaiser1061e722003-01-04 01:43:53 +00001074 def view_restart_mark(self, event=None):
1075 self.text.see("iomark")
1076 self.text.see("restart")
1077
1078 def restart_shell(self, event=None):
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +00001079 self.interp.restart_subprocess()
Kurt B. Kaiser1061e722003-01-04 01:43:53 +00001080
David Scherer7aced172000-08-15 01:13:23 +00001081 def showprompt(self):
1082 self.resetoutput()
1083 try:
1084 s = str(sys.ps1)
1085 except:
1086 s = ""
1087 self.console.write(s)
1088 self.text.mark_set("insert", "end-1c")
Chui Tey5d2af632002-05-26 13:36:41 +00001089 self.set_line_and_column()
Kurt B. Kaiserdc1e7092002-07-11 04:33:41 +00001090 self.io.reset_undo()
David Scherer7aced172000-08-15 01:13:23 +00001091
1092 def resetoutput(self):
1093 source = self.text.get("iomark", "end-1c")
1094 if self.history:
1095 self.history.history_store(source)
1096 if self.text.get("end-2c") != "\n":
1097 self.text.insert("end-1c", "\n")
1098 self.text.mark_set("iomark", "end-1c")
Chui Tey5d2af632002-05-26 13:36:41 +00001099 self.set_line_and_column()
David Scherer7aced172000-08-15 01:13:23 +00001100 sys.stdout.softspace = 0
1101
1102 def write(self, s, tags=()):
Kurt B. Kaiser003091c2003-02-17 18:57:16 +00001103 try:
1104 self.text.mark_gravity("iomark", "right")
1105 OutputWindow.write(self, s, tags, "iomark")
1106 self.text.mark_gravity("iomark", "left")
1107 except:
1108 pass
David Scherer7aced172000-08-15 01:13:23 +00001109 if self.canceled:
1110 self.canceled = 0
Kurt B. Kaiser7f38ec02003-05-15 03:19:42 +00001111 if not use_subprocess:
1112 raise KeyboardInterrupt
David Scherer7aced172000-08-15 01:13:23 +00001113
1114class PseudoFile:
1115
Martin v. Löwisbcc651a2003-06-22 07:52:56 +00001116 def __init__(self, shell, tags, encoding=None):
David Scherer7aced172000-08-15 01:13:23 +00001117 self.shell = shell
1118 self.tags = tags
Chui Tey5d2af632002-05-26 13:36:41 +00001119 self.softspace = 0
Martin v. Löwisbcc651a2003-06-22 07:52:56 +00001120 self.encoding = encoding
David Scherer7aced172000-08-15 01:13:23 +00001121
1122 def write(self, s):
1123 self.shell.write(s, self.tags)
1124
1125 def writelines(self, l):
1126 map(self.write, l)
1127
1128 def flush(self):
1129 pass
1130
1131 def isatty(self):
Kurt B. Kaiser837d15c2002-09-18 02:29:59 +00001132 return True
David Scherer7aced172000-08-15 01:13:23 +00001133
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001134
David Scherer7aced172000-08-15 01:13:23 +00001135usage_msg = """\
David Scherer7aced172000-08-15 01:13:23 +00001136
Kurt B. Kaiser11659ad2003-05-15 23:23:21 +00001137USAGE: idle [-deins] [-t title] [file]*
1138 idle [-dns] [-t title] (-c cmd | -r file) [arg]*
1139 idle [-dns] [-t title] - [arg]*
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001140
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001141 -h print this help message and exit
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001142 -n run IDLE without a subprocess (see Help/IDLE Help for details)
David Scherer7aced172000-08-15 01:13:23 +00001143
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001144The following options will override the IDLE 'settings' configuration:
Kurt B. Kaiser96d88422001-07-17 04:59:01 +00001145
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001146 -e open an edit window
1147 -i open a shell window
1148
1149The following options imply -i and will open a shell:
1150
1151 -c cmd run the command in a shell, or
1152 -r file run script from file
1153
1154 -d enable the debugger
1155 -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1156 -t title set title of shell window
1157
1158A default edit window will be bypassed when -c, -r, or - are used.
1159
1160[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1161
1162Examples:
1163
1164idle
1165 Open an edit window or shell depending on IDLE's configuration.
1166
1167idle foo.py foobar.py
1168 Edit the files, also open a shell if configured to start with shell.
1169
1170idle -est "Baz" foo.py
1171 Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1172 window with the title "Baz".
1173
1174idle -c "import sys; print sys.argv" "foo"
1175 Open a shell window and run the command, passing "-c" in sys.argv[0]
1176 and "foo" in sys.argv[1].
1177
1178idle -d -s -r foo.py "Hello World"
1179 Open a shell window, run a startup script, enable the debugger, and
1180 run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1181 sys.argv[1].
1182
1183echo "import sys; print sys.argv" | idle - "foobar"
1184 Open a shell window, run the script piped in, passing '' in sys.argv[0]
1185 and "foobar" in sys.argv[1].
David Scherer7aced172000-08-15 01:13:23 +00001186"""
1187
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001188def main():
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001189 global flist, root, use_subprocess
David Scherer7aced172000-08-15 01:13:23 +00001190
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001191 use_subprocess = True
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001192 enable_shell = False
1193 enable_edit = False
1194 debug = False
1195 cmd = None
1196 script = None
1197 startup = False
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001198 try:
Kurt B. Kaiser4ada7ad2002-12-29 22:03:38 +00001199 sys.ps1
1200 except AttributeError:
1201 sys.ps1 = '>>> '
1202 try:
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001203 opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001204 except getopt.error, msg:
1205 sys.stderr.write("Error: %s\n" % str(msg))
1206 sys.stderr.write(usage_msg)
1207 sys.exit(2)
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001208 for o, a in opts:
1209 if o == '-c':
1210 cmd = a
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001211 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001212 if o == '-d':
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001213 debug = True
1214 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001215 if o == '-e':
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001216 enable_edit = True
1217 if o == '-h':
1218 sys.stdout.write(usage_msg)
1219 sys.exit()
1220 if o == '-i':
1221 enable_shell = True
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001222 if o == '-n':
1223 use_subprocess = False
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001224 if o == '-r':
1225 script = a
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001226 if os.path.isfile(script):
1227 pass
1228 else:
1229 print "No script file: ", script
1230 sys.exit()
1231 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001232 if o == '-s':
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001233 startup = True
1234 enable_shell = True
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001235 if o == '-t':
1236 PyShell.shell_title = a
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001237 enable_shell = True
1238 if args and args[0] == '-':
1239 cmd = sys.stdin.read()
1240 enable_shell = True
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001241 # process sys.argv and sys.path:
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001242 for i in range(len(sys.path)):
1243 sys.path[i] = os.path.abspath(sys.path[i])
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001244 if args and args[0] == '-':
1245 sys.argv = [''] + args[1:]
1246 elif cmd:
1247 sys.argv = ['-c'] + args
1248 elif script:
1249 sys.argv = [script] + args
1250 elif args:
1251 enable_edit = True
1252 pathx = []
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001253 for filename in args:
1254 pathx.append(os.path.dirname(filename))
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001255 for dir in pathx:
1256 dir = os.path.abspath(dir)
1257 if not dir in sys.path:
1258 sys.path.insert(0, dir)
Kurt B. Kaiserff002b92002-12-21 21:39:11 +00001259 else:
1260 dir = os.getcwd()
1261 if not dir in sys.path:
1262 sys.path.insert(0, dir)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001263 # check the IDLE settings configuration (but command line overrides)
1264 edit_start = idleConf.GetOption('main', 'General',
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001265 'editor-on-startup', type='bool')
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001266 enable_edit = enable_edit or edit_start
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001267 enable_shell = enable_shell or not edit_start
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001268 # start editor and/or shell windows:
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001269 root = Tk(className="Idle")
1270 fixwordbreaks(root)
1271 root.withdraw()
1272 flist = PyShellFileList(root)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001273 if enable_edit:
1274 if not (cmd or script):
1275 for filename in args:
1276 flist.open(filename)
1277 if not args:
1278 flist.new()
1279 if enable_shell:
1280 flist.open_shell()
1281 elif enable_shell:
1282 flist.pyshell = PyShell(flist)
1283 flist.pyshell.begin()
1284 shell = flist.pyshell
1285 # handle remaining options:
1286 if debug:
1287 shell.open_debugger()
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001288 if startup:
1289 filename = os.environ.get("IDLESTARTUP") or \
1290 os.environ.get("PYTHONSTARTUP")
1291 if filename and os.path.isfile(filename):
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001292 shell.interp.execfile(filename)
1293 if cmd or script:
1294 shell.interp.runcommand("""if 1:
1295 import sys as _sys
1296 _sys.argv = %s
1297 del _sys
1298 \n""" % `sys.argv`)
1299 if cmd:
1300 shell.interp.execsource(cmd)
1301 elif script:
Kurt B. Kaiser11659ad2003-05-15 23:23:21 +00001302 shell.interp.prepend_syspath(script)
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001303 shell.interp.execfile(script)
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001304 root.mainloop()
1305 root.destroy()
1306
Kurt B. Kaiserf06eed02002-12-11 04:42:04 +00001307
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001308def display_port_binding_error():
1309 print """\
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001310\nIDLE cannot run.
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001311
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001312IDLE needs to use a specific TCP/IP port (8833) in order to communicate with
1313its Python execution server. IDLE is unable to bind to this port, and so
1314cannot start. Here are some possible causes of this problem:
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001315
1316 1. TCP/IP networking is not installed or not working on this computer
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001317 2. Another program (another IDLE?) is running that uses this port
Kurt B. Kaiser969de452002-06-12 03:28:57 +00001318 3. Personal firewall software is preventing IDLE from using this port
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001319
Kurt B. Kaiser8f570a72003-05-15 18:52:51 +00001320Run IDLE with the -n command line switch to start without a subprocess
1321and refer to Help/IDLE Help "Running without a subprocess" for further
1322details.
Steven M. Gava1f733ba2001-10-07 11:44:49 +00001323"""
David Scherer7aced172000-08-15 01:13:23 +00001324
1325if __name__ == "__main__":
Kurt B. Kaiser9e8b8282003-06-15 17:38:45 +00001326 sys.modules['PyShell'] = sys.modules['__main__']
David Scherer7aced172000-08-15 01:13:23 +00001327 main()