Mercurial > cpython-lru_cache-weakref
annotate Lib/idlelib/PyShell.py @ 23547:b74afdd072eb legacy-trunk
GvR's rpc patch
| author | Chui Tey <chui.tey@advdata.com.au> |
|---|---|
| date | Sun, 26 May 2002 13:36:41 +0000 |
| parents | 194ed5e0dc8f |
| children | 24b0f6d693e3 |
| rev | line source |
|---|---|
| 13975 | 1 #! /usr/bin/env python |
| 2 | |
| 3 # changes by dscherer@cmu.edu | |
| 4 | |
|
18613
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
5 # The main() function has been replaced by a whole class, in order to |
| 13975 | 6 # address the constraint that only one process can sit on the port |
| 7 # hard-coded into the loader. | |
| 8 | |
| 9 # It attempts to load the RPC protocol server and publish itself. If | |
| 10 # that fails, it assumes that some other copy of IDLE is already running | |
| 11 # on the port and attempts to contact it. It then uses the RPC mechanism | |
| 12 # to ask that copy to do whatever it was instructed (via the command | |
| 13 # line) to do. (Think netscape -remote). The handling of command line | |
| 14 # arguments for remotes is still very incomplete. | |
| 15 | |
|
18613
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
16 # Default behavior (no command line options) is to open an editor window |
|
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
17 # instead of starting the Python Shell. However, if called as |
|
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
18 # Pyshell.main(0), the Shell will be started instead of the editor window. |
| 13975 | 19 |
|
18613
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
20 # In the default editor mode, if files are specified, they are opened. |
|
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
21 |
|
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
22 # If any command line options are specified, a shell does appear, and if |
|
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
23 # the -e option is used, both a shell and an editor window open. |
| 13975 | 24 |
| 25 import os | |
| 26 import spawn | |
| 27 import sys | |
| 28 import string | |
| 29 import getopt | |
| 30 import re | |
| 31 import protocol | |
| 23547 | 32 import socket |
| 33 import time | |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
34 import warnings |
| 23547 | 35 import traceback |
| 13975 | 36 |
| 37 import linecache | |
| 38 from code import InteractiveInterpreter | |
| 39 | |
| 40 from Tkinter import * | |
| 41 import tkMessageBox | |
| 42 | |
| 43 from EditorWindow import EditorWindow, fixwordbreaks | |
| 44 from FileList import FileList | |
| 45 from ColorDelegator import ColorDelegator | |
| 46 from UndoDelegator import UndoDelegator | |
| 47 from OutputWindow import OutputWindow, OnDemandOutputWindow | |
|
20864
8957341f98f8
further config system work
Steven M. Gava <elguavas@python.net>
parents:
20306
diff
changeset
|
48 from configHandler import idleConf |
| 13975 | 49 import idlever |
| 50 | |
| 23547 | 51 import rpc |
| 52 | |
| 53 use_subprocess = 0 # Set to 1 to spawn subprocess for command execution | |
| 54 | |
| 55 # Change warnings module to write to sys.__stderr__ | |
| 56 try: | |
| 57 import warnings | |
| 58 except ImportError: | |
| 59 pass | |
| 60 else: | |
| 61 def idle_showwarning(message, category, filename, lineno): | |
| 62 file = sys.__stderr__ | |
| 63 file.write(warnings.formatwarning(message, category, filename, lineno)) | |
| 64 warnings.showwarning = idle_showwarning | |
| 65 | |
| 13975 | 66 # We need to patch linecache.checkcache, because we don't want it |
| 67 # to throw away our <pyshell#...> entries. | |
| 68 # Rather than repeating its code here, we save those entries, | |
| 69 # then call the original function, and then restore the saved entries. | |
| 70 def linecache_checkcache(orig_checkcache=linecache.checkcache): | |
| 71 cache = linecache.cache | |
| 72 save = {} | |
| 73 for filename in cache.keys(): | |
| 74 if filename[:1] + filename[-1:] == '<>': | |
| 75 save[filename] = cache[filename] | |
| 76 orig_checkcache() | |
| 77 cache.update(save) | |
| 78 linecache.checkcache = linecache_checkcache | |
| 79 | |
| 80 | |
| 81 # Note: <<newline-and-indent>> event is defined in AutoIndent.py | |
| 82 | |
| 83 #$ event <<plain-newline-and-indent>> | |
| 84 #$ win <Control-j> | |
| 85 #$ unix <Control-j> | |
| 86 | |
| 87 #$ event <<beginning-of-line>> | |
| 88 #$ win <Control-a> | |
| 89 #$ win <Home> | |
| 90 #$ unix <Control-a> | |
| 91 #$ unix <Home> | |
| 92 | |
| 93 #$ event <<history-next>> | |
| 94 #$ win <Alt-n> | |
| 95 #$ unix <Alt-n> | |
| 96 | |
| 97 #$ event <<history-previous>> | |
| 98 #$ win <Alt-p> | |
| 99 #$ unix <Alt-p> | |
| 100 | |
| 101 #$ event <<interrupt-execution>> | |
| 102 #$ win <Control-c> | |
| 103 #$ unix <Control-c> | |
| 104 | |
| 105 #$ event <<end-of-file>> | |
| 106 #$ win <Control-d> | |
| 107 #$ unix <Control-d> | |
| 108 | |
| 109 #$ event <<open-stack-viewer>> | |
| 110 | |
| 111 #$ event <<toggle-debugger>> | |
| 112 | |
| 113 | |
| 114 class PyShellEditorWindow(EditorWindow): | |
| 115 | |
| 116 # Regular text edit window when a shell is present | |
| 117 # XXX ought to merge with regular editor window | |
| 118 | |
| 119 def __init__(self, *args): | |
| 120 apply(EditorWindow.__init__, (self,) + args) | |
| 121 self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here) | |
| 122 self.text.bind("<<open-python-shell>>", self.flist.open_shell) | |
| 123 | |
| 124 rmenu_specs = [ | |
| 125 ("Set breakpoint here", "<<set-breakpoint-here>>"), | |
| 126 ] | |
| 127 | |
| 128 def set_breakpoint_here(self, event=None): | |
| 129 if not self.flist.pyshell or not self.flist.pyshell.interp.debugger: | |
| 130 self.text.bell() | |
| 131 return | |
| 132 self.flist.pyshell.interp.debugger.set_breakpoint_here(self) | |
| 133 | |
| 134 | |
| 135 class PyShellFileList(FileList): | |
| 136 | |
| 137 # File list when a shell is present | |
| 138 | |
| 139 EditorWindow = PyShellEditorWindow | |
| 140 | |
| 141 pyshell = None | |
| 142 | |
| 143 def open_shell(self, event=None): | |
| 144 if self.pyshell: | |
| 145 self.pyshell.wakeup() | |
| 146 else: | |
| 147 self.pyshell = PyShell(self) | |
| 148 self.pyshell.begin() | |
| 149 return self.pyshell | |
| 150 | |
| 151 | |
| 152 class ModifiedColorDelegator(ColorDelegator): | |
| 153 | |
| 154 # Colorizer for the shell window itself | |
|
22111
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
155 |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
156 def __init__(self): |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
157 ColorDelegator.__init__(self) |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
158 self.LoadTagDefs() |
| 13975 | 159 |
| 160 def recolorize_main(self): | |
| 161 self.tag_remove("TODO", "1.0", "iomark") | |
| 162 self.tag_add("SYNC", "1.0", "iomark") | |
| 163 ColorDelegator.recolorize_main(self) | |
|
22111
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
164 |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
165 def LoadTagDefs(self): |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
166 ColorDelegator.LoadTagDefs(self) |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
167 theme = idleConf.GetOption('main','Theme','name') |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
168 self.tagdefs.update({ |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
169 "stdin": {'background':None,'foreground':None}, |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
170 "stdout": idleConf.GetHighlight(theme, "stdout"), |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
171 "stderr": idleConf.GetHighlight(theme, "stderr"), |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
172 "console": idleConf.GetHighlight(theme, "console"), |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
173 "ERROR": idleConf.GetHighlight(theme, "error"), |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
174 None: idleConf.GetHighlight(theme, "normal"), |
|
c494084dc6d8
First work on making config changes dynamic,
Steven M. Gava <elguavas@python.net>
parents:
21627
diff
changeset
|
175 }) |
| 13975 | 176 |
| 177 class ModifiedUndoDelegator(UndoDelegator): | |
| 178 | |
| 179 # Forbid insert/delete before the I/O mark | |
| 180 | |
| 181 def insert(self, index, chars, tags=None): | |
| 182 try: | |
| 183 if self.delegate.compare(index, "<", "iomark"): | |
| 184 self.delegate.bell() | |
| 185 return | |
| 186 except TclError: | |
| 187 pass | |
| 188 UndoDelegator.insert(self, index, chars, tags) | |
| 189 | |
| 190 def delete(self, index1, index2=None): | |
| 191 try: | |
| 192 if self.delegate.compare(index1, "<", "iomark"): | |
| 193 self.delegate.bell() | |
| 194 return | |
| 195 except TclError: | |
| 196 pass | |
| 197 UndoDelegator.delete(self, index1, index2) | |
| 198 | |
| 199 class ModifiedInterpreter(InteractiveInterpreter): | |
| 200 | |
| 201 def __init__(self, tkconsole): | |
| 202 self.tkconsole = tkconsole | |
| 203 locals = sys.modules['__main__'].__dict__ | |
| 204 InteractiveInterpreter.__init__(self, locals=locals) | |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
205 self.save_warnings_filters = None |
| 13975 | 206 |
| 23547 | 207 global flist |
| 208 self.output = OnDemandOutputWindow(flist) | |
| 209 | |
| 210 rpcclt = None | |
| 211 rpcpid = None | |
| 212 | |
| 213 def spawn_subprocess(self): | |
| 214 port = 8833 | |
| 215 addr = ("localhost", port) | |
| 216 w = ['-W' + s for s in sys.warnoptions] | |
| 217 args = [sys.executable] + w + ["-c", "__import__('run').main()", | |
| 218 str(port)] | |
| 219 self.rpcpid = os.spawnv(os.P_NOWAIT, args[0], args) | |
| 220 for i in range(5): | |
| 221 time.sleep(i) | |
| 222 try: | |
| 223 self.rpcclt = rpc.RPCClient(addr) | |
| 224 break | |
| 225 except socket.error, err: | |
| 226 if i > 3: | |
| 227 print >>sys.__stderr__, "Socket error:", err, "; retry..." | |
| 228 else: | |
| 229 # XXX Make this a dialog? | |
| 230 print >>sys.__stderr__, "Can't spawn subprocess!" | |
| 231 return | |
| 232 self.output.stdout=PseudoFile(self.output, "stdout") | |
| 233 self.output.stderr=PseudoFile(self.output, "stderr") | |
| 234 self.rpcclt.register("stdin", self.output) | |
| 235 self.rpcclt.register("stdout", self.output.stdout) | |
| 236 self.rpcclt.register("stderr", self.output.stderr) | |
| 237 self.rpcclt.register("flist", self.tkconsole.flist) | |
| 238 self.poll_subprocess() | |
| 239 | |
| 240 active_seq = None | |
| 241 | |
| 242 def poll_subprocess(self): | |
| 243 clt = self.rpcclt | |
| 244 if clt is None: | |
| 245 return | |
| 246 response = clt.pollresponse(self.active_seq) | |
| 247 self.tkconsole.text.after(50, self.poll_subprocess) | |
| 248 if response: | |
| 249 self.tkconsole.resetoutput() | |
| 250 self.active_seq = None | |
| 251 how, what = response | |
| 252 file = self.tkconsole.console | |
| 253 if how == "OK": | |
| 254 if what is not None: | |
| 255 print >>file, `what` | |
| 256 elif how == "EXCEPTION": | |
| 257 mod, name, args, tb = what | |
| 258 print >>file, 'Traceback (most recent call last):' | |
| 259 while tb and tb[0][0] in ("run.py", "rpc.py"): | |
| 260 del tb[0] | |
| 261 while tb and tb[-1][0] in ("run.py", "rpc.py"): | |
| 262 del tb[-1] | |
| 263 for i in range(len(tb)): | |
| 264 fn, ln, nm, line = tb[i] | |
| 265 if not line and fn.startswith("<pyshell#"): | |
| 266 line = linecache.getline(fn, ln) | |
| 267 tb[i] = fn, ln, nm, line | |
| 268 traceback.print_list(tb, file=file) | |
| 269 if mod and mod != "exceptions": | |
| 270 name = mod + "." + name | |
| 271 print >>file, name + ":", " ".join(map(str, args)) | |
| 272 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): | |
| 273 self.remote_stack_viewer() | |
| 274 elif how == "ERROR": | |
| 275 print >>sys.__stderr__, "Oops:", how, what | |
| 276 print >>file, "Oops:", how, what | |
| 277 self.tkconsole.endexecuting() | |
| 278 | |
| 279 def kill_subprocess(self): | |
| 280 clt = self.rpcclt | |
| 281 self.rpcclt = None | |
| 282 if clt is not None: | |
| 283 clt.close() | |
| 284 | |
| 285 def remote_stack_viewer(self): | |
| 286 import RemoteObjectBrowser | |
| 287 oid = self.rpcclt.remotecall("exec", "stackviewer", ("flist",), {}) | |
| 288 if oid is None: | |
| 289 self.tkconsole.root.bell() | |
| 290 return | |
| 291 item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) | |
| 292 from TreeWidget import ScrolledCanvas, TreeNode | |
| 293 top = Toplevel(self.tkconsole.root) | |
| 294 sc = ScrolledCanvas(top, bg="white", highlightthickness=0) | |
| 295 sc.frame.pack(expand=1, fill="both") | |
| 296 node = TreeNode(sc.canvas, None, item) | |
| 297 node.expand() | |
| 298 # XXX Should GC the remote tree when closing the window | |
| 299 | |
| 13975 | 300 gid = 0 |
| 301 | |
| 302 def execsource(self, source): | |
| 303 # Like runsource() but assumes complete exec source | |
| 304 filename = self.stuffsource(source) | |
| 305 self.execfile(filename, source) | |
| 306 | |
| 307 def execfile(self, filename, source=None): | |
| 308 # Execute an existing file | |
| 309 if source is None: | |
| 310 source = open(filename, "r").read() | |
| 311 try: | |
| 312 code = compile(source, filename, "exec") | |
| 313 except (OverflowError, SyntaxError): | |
| 314 self.tkconsole.resetoutput() | |
| 315 InteractiveInterpreter.showsyntaxerror(self, filename) | |
| 316 else: | |
| 317 self.runcode(code) | |
| 318 | |
| 319 def runsource(self, source): | |
| 320 # Extend base class to stuff the source in the line cache first | |
| 321 filename = self.stuffsource(source) | |
| 322 self.more = 0 | |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
323 self.save_warnings_filters = warnings.filters[:] |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
324 warnings.filterwarnings(action="error", category=SyntaxWarning) |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
325 try: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
326 return InteractiveInterpreter.runsource(self, source, filename) |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
327 finally: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
328 if self.save_warnings_filters is not None: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
329 warnings.filters[:] = self.save_warnings_filters |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
330 self.save_warnings_filters = None |
| 13975 | 331 |
| 332 def stuffsource(self, source): | |
| 333 # Stuff source in the filename cache | |
| 334 filename = "<pyshell#%d>" % self.gid | |
| 335 self.gid = self.gid + 1 | |
| 336 lines = string.split(source, "\n") | |
| 337 linecache.cache[filename] = len(source)+1, 0, lines, filename | |
| 338 return filename | |
| 339 | |
| 340 def showsyntaxerror(self, filename=None): | |
| 341 # Extend base class to color the offending position | |
| 342 # (instead of printing it and pointing at it with a caret) | |
| 343 text = self.tkconsole.text | |
| 344 stuff = self.unpackerror() | |
| 345 if not stuff: | |
| 346 self.tkconsole.resetoutput() | |
| 347 InteractiveInterpreter.showsyntaxerror(self, filename) | |
| 348 return | |
| 349 msg, lineno, offset, line = stuff | |
| 350 if lineno == 1: | |
| 351 pos = "iomark + %d chars" % (offset-1) | |
| 352 else: | |
| 353 pos = "iomark linestart + %d lines + %d chars" % (lineno-1, | |
| 354 offset-1) | |
| 355 text.tag_add("ERROR", pos) | |
| 356 text.see(pos) | |
| 357 char = text.get(pos) | |
| 358 if char and char in string.letters + string.digits + "_": | |
| 359 text.tag_add("ERROR", pos + " wordstart", pos) | |
| 360 self.tkconsole.resetoutput() | |
| 361 self.write("SyntaxError: %s\n" % str(msg)) | |
| 362 | |
| 363 def unpackerror(self): | |
| 364 type, value, tb = sys.exc_info() | |
| 365 ok = type is SyntaxError | |
| 366 if ok: | |
| 367 try: | |
| 368 msg, (dummy_filename, lineno, offset, line) = value | |
| 369 except: | |
| 370 ok = 0 | |
| 371 if ok: | |
| 372 return msg, lineno, offset, line | |
| 373 else: | |
| 374 return None | |
| 375 | |
| 376 def showtraceback(self): | |
| 377 # Extend base class method to reset output properly | |
| 378 self.tkconsole.resetoutput() | |
| 379 self.checklinecache() | |
| 380 InteractiveInterpreter.showtraceback(self) | |
| 23547 | 381 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): |
| 382 self.tkconsole.open_stack_viewer() | |
| 13975 | 383 |
| 384 def checklinecache(self): | |
| 385 c = linecache.cache | |
| 386 for key in c.keys(): | |
| 387 if key[:1] + key[-1:] != "<>": | |
| 388 del c[key] | |
| 389 | |
| 390 debugger = None | |
| 391 | |
| 392 def setdebugger(self, debugger): | |
| 393 self.debugger = debugger | |
| 394 | |
| 395 def getdebugger(self): | |
| 396 return self.debugger | |
| 397 | |
| 23547 | 398 def runcommand(self, code): |
| 399 # This runs the code without invoking the debugger. | |
| 400 # The code better not raise an exception! | |
| 401 if self.tkconsole.executing: | |
| 402 tkMessageBox.showerror( | |
| 403 "Already executing", | |
| 404 "The Python Shell window is already executing a command; " | |
| 405 "please wait until it is finished.", | |
| 406 master=self.tkconsole.text) | |
| 407 return 0 | |
| 408 if self.rpcclt: | |
| 409 self.rpcclt.remotecall("exec", "runcode", (code,), {}) | |
| 410 else: | |
| 411 exec code in self.locals | |
| 412 return 1 | |
| 413 | |
| 13975 | 414 def runcode(self, code): |
| 415 # Override base class method | |
| 23547 | 416 if self.tkconsole.executing: |
| 417 tkMessageBox.showerror( | |
| 418 "Already executing", | |
| 419 "The Python Shell window is already executing a command; " | |
| 420 "please wait until it is finished.", | |
| 421 master=self.tkconsole.text) | |
| 422 return | |
| 423 | |
| 424 self.checklinecache() | |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
425 if self.save_warnings_filters is not None: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
426 warnings.filters[:] = self.save_warnings_filters |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
427 self.save_warnings_filters = None |
| 13975 | 428 debugger = self.debugger |
| 23547 | 429 if not debugger and self.rpcclt is not None: |
| 430 self.tkconsole.beginexecuting() | |
| 431 self.active_seq = self.rpcclt.asynccall("exec", "runcode", | |
| 432 (code,), {}) | |
| 433 return | |
| 434 | |
| 13975 | 435 try: |
| 436 self.tkconsole.beginexecuting() | |
| 437 try: | |
| 438 if debugger: | |
| 439 debugger.run(code, self.locals) | |
| 440 else: | |
| 441 exec code in self.locals | |
| 442 except SystemExit: | |
| 443 if tkMessageBox.askyesno( | |
| 444 "Exit?", | |
| 445 "Do you want to exit altogether?", | |
| 446 default="yes", | |
| 447 master=self.tkconsole.text): | |
| 448 raise | |
| 449 else: | |
| 450 self.showtraceback() | |
| 451 except: | |
| 452 self.showtraceback() | |
| 453 | |
| 454 finally: | |
| 455 self.tkconsole.endexecuting() | |
| 456 | |
| 457 def write(self, s): | |
| 458 # Override base class write | |
| 459 self.tkconsole.console.write(s) | |
| 460 | |
| 461 class PyShell(OutputWindow): | |
| 462 | |
| 463 shell_title = "Python Shell" | |
| 464 | |
| 465 # Override classes | |
| 466 ColorDelegator = ModifiedColorDelegator | |
| 467 UndoDelegator = ModifiedUndoDelegator | |
| 468 | |
| 469 # Override menu bar specs | |
| 470 menu_specs = PyShellEditorWindow.menu_specs[:] | |
|
21035
c4499596b1a4
back in harness on new config system
Steven M. Gava <elguavas@python.net>
parents:
20864
diff
changeset
|
471 menu_specs.insert(len(menu_specs)-3, ("debug", "_Debug")) |
| 13975 | 472 |
| 473 # New classes | |
| 474 from IdleHistory import History | |
| 475 | |
| 476 def __init__(self, flist=None): | |
| 477 self.interp = ModifiedInterpreter(self) | |
| 478 if flist is None: | |
| 479 root = Tk() | |
| 480 fixwordbreaks(root) | |
| 481 root.withdraw() | |
| 482 flist = PyShellFileList(root) | |
| 483 | |
| 484 OutputWindow.__init__(self, flist, None, None) | |
| 485 | |
| 486 import __builtin__ | |
| 487 __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D." | |
| 488 | |
| 489 self.auto = self.extensions["AutoIndent"] # Required extension | |
| 490 self.auto.config(usetabs=1, indentwidth=8, context_use_ps1=1) | |
| 491 | |
| 492 text = self.text | |
| 493 text.configure(wrap="char") | |
| 494 text.bind("<<newline-and-indent>>", self.enter_callback) | |
| 495 text.bind("<<plain-newline-and-indent>>", self.linefeed_callback) | |
| 496 text.bind("<<interrupt-execution>>", self.cancel_callback) | |
| 497 text.bind("<<beginning-of-line>>", self.home_callback) | |
| 498 text.bind("<<end-of-file>>", self.eof_callback) | |
| 499 text.bind("<<open-stack-viewer>>", self.open_stack_viewer) | |
| 500 text.bind("<<toggle-debugger>>", self.toggle_debugger) | |
| 501 text.bind("<<open-python-shell>>", self.flist.open_shell) | |
| 502 text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer) | |
| 503 | |
| 504 self.save_stdout = sys.stdout | |
| 505 self.save_stderr = sys.stderr | |
| 506 self.save_stdin = sys.stdin | |
| 23547 | 507 self.stdout = PseudoFile(self, "stdout") |
| 508 self.stderr = PseudoFile(self, "stderr") | |
| 13975 | 509 self.console = PseudoFile(self, "console") |
| 23547 | 510 if not use_subprocess: |
| 511 sys.stdout = self.stdout | |
| 512 sys.stderr = self.stderr | |
| 513 sys.stdin = self | |
| 13975 | 514 |
| 515 self.history = self.History(self.text) | |
| 516 | |
| 23547 | 517 if use_subprocess: |
| 518 self.interp.spawn_subprocess() | |
| 519 | |
| 13975 | 520 reading = 0 |
| 521 executing = 0 | |
| 522 canceled = 0 | |
| 523 endoffile = 0 | |
| 524 | |
| 525 def toggle_debugger(self, event=None): | |
| 526 if self.executing: | |
| 527 tkMessageBox.showerror("Don't debug now", | |
| 528 "You can only toggle the debugger when idle", | |
| 529 master=self.text) | |
| 530 self.set_debugger_indicator() | |
| 531 return "break" | |
| 532 else: | |
| 533 db = self.interp.getdebugger() | |
| 534 if db: | |
| 535 self.close_debugger() | |
| 536 else: | |
| 537 self.open_debugger() | |
| 538 | |
| 539 def set_debugger_indicator(self): | |
| 540 db = self.interp.getdebugger() | |
| 541 self.setvar("<<toggle-debugger>>", not not db) | |
| 542 | |
| 543 def toggle_jit_stack_viewer( self, event=None): | |
| 544 pass # All we need is the variable | |
| 545 | |
| 546 def close_debugger(self): | |
| 547 db = self.interp.getdebugger() | |
| 548 if db: | |
| 549 self.interp.setdebugger(None) | |
| 550 db.close() | |
| 551 self.resetoutput() | |
| 552 self.console.write("[DEBUG OFF]\n") | |
| 553 sys.ps1 = ">>> " | |
| 554 self.showprompt() | |
| 555 self.set_debugger_indicator() | |
| 556 | |
| 557 def open_debugger(self): | |
| 23547 | 558 if self.interp.rpcclt: |
| 559 return self.open_remote_debugger() | |
| 13975 | 560 import Debugger |
| 561 self.interp.setdebugger(Debugger.Debugger(self)) | |
| 562 sys.ps1 = "[DEBUG ON]\n>>> " | |
| 563 self.showprompt() | |
| 564 self.set_debugger_indicator() | |
| 565 | |
| 23547 | 566 def open_remote_debugger(self): |
| 567 import RemoteDebugger | |
| 568 gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, self) | |
| 569 self.interp.setdebugger(gui) | |
| 570 sys.ps1 = "[DEBUG ON]\n>>> " | |
| 571 self.showprompt() | |
| 572 self.set_debugger_indicator() | |
| 573 | |
| 13975 | 574 def beginexecuting(self): |
| 575 # Helper for ModifiedInterpreter | |
| 576 self.resetoutput() | |
| 577 self.executing = 1 | |
| 578 ##self._cancel_check = self.cancel_check | |
| 579 ##sys.settrace(self._cancel_check) | |
| 580 | |
| 581 def endexecuting(self): | |
| 582 # Helper for ModifiedInterpreter | |
| 583 ##sys.settrace(None) | |
| 584 ##self._cancel_check = None | |
| 585 self.executing = 0 | |
| 586 self.canceled = 0 | |
| 23547 | 587 self.showprompt() |
| 13975 | 588 |
| 589 def close(self): | |
| 590 # Extend base class method | |
| 591 if self.executing: | |
| 592 # XXX Need to ask a question here | |
| 593 if not tkMessageBox.askokcancel( | |
| 594 "Kill?", | |
| 595 "The program is still running; do you want to kill it?", | |
| 596 default="ok", | |
| 597 master=self.text): | |
| 598 return "cancel" | |
| 599 self.canceled = 1 | |
| 600 if self.reading: | |
| 601 self.top.quit() | |
| 602 return "cancel" | |
|
18586
fe44428f9774
py-cvs-2001_07_13 (Rev 1.34) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
18560
diff
changeset
|
603 return OutputWindow.close(self) |
| 13975 | 604 |
| 605 def _close(self): | |
| 606 self.close_debugger() | |
| 23547 | 607 self.interp.kill_subprocess() |
| 13975 | 608 # Restore std streams |
| 609 sys.stdout = self.save_stdout | |
| 610 sys.stderr = self.save_stderr | |
| 611 sys.stdin = self.save_stdin | |
| 612 # Break cycles | |
| 613 self.interp = None | |
| 614 self.console = None | |
| 615 self.auto = None | |
| 616 self.flist.pyshell = None | |
| 617 self.history = None | |
| 618 OutputWindow._close(self) # Really EditorWindow._close | |
| 619 | |
| 620 def ispythonsource(self, filename): | |
| 621 # Override this so EditorWindow never removes the colorizer | |
| 622 return 1 | |
| 623 | |
| 624 def short_title(self): | |
| 625 return self.shell_title | |
| 626 | |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
627 COPYRIGHT = \ |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
628 'Type "copyright", "credits" or "license" for more information.' |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
629 |
| 13975 | 630 def begin(self): |
| 631 self.resetoutput() | |
|
18614
384a61fa6f5a
Call out IDLE Fork in startup message.
Kurt B. Kaiser <kbk@shore.net>
parents:
18613
diff
changeset
|
632 self.write("Python %s on %s\n%s\nIDLE Fork %s -- press F1 for help\n" % |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
633 (sys.version, sys.platform, self.COPYRIGHT, |
| 13975 | 634 idlever.IDLE_VERSION)) |
| 635 try: | |
| 636 sys.ps1 | |
| 637 except AttributeError: | |
| 638 sys.ps1 = ">>> " | |
| 639 self.showprompt() | |
| 640 import Tkinter | |
| 641 Tkinter._default_root = None | |
| 642 | |
| 643 def interact(self): | |
| 644 self.begin() | |
| 645 self.top.mainloop() | |
| 646 | |
| 647 def readline(self): | |
| 648 save = self.reading | |
| 649 try: | |
| 650 self.reading = 1 | |
| 651 self.top.mainloop() | |
| 652 finally: | |
| 653 self.reading = save | |
| 654 line = self.text.get("iomark", "end-1c") | |
| 655 self.resetoutput() | |
| 656 if self.canceled: | |
| 657 self.canceled = 0 | |
| 658 raise KeyboardInterrupt | |
| 659 if self.endoffile: | |
| 660 self.endoffile = 0 | |
| 661 return "" | |
| 662 return line | |
| 663 | |
| 664 def isatty(self): | |
| 665 return 1 | |
| 666 | |
| 667 def cancel_callback(self, event): | |
| 668 try: | |
| 669 if self.text.compare("sel.first", "!=", "sel.last"): | |
| 670 return # Active selection -- always use default binding | |
| 671 except: | |
| 672 pass | |
| 673 if not (self.executing or self.reading): | |
| 674 self.resetoutput() | |
| 675 self.write("KeyboardInterrupt\n") | |
| 676 self.showprompt() | |
| 677 return "break" | |
| 678 self.endoffile = 0 | |
| 679 if self.reading: | |
| 23547 | 680 self.canceled = 1 |
| 13975 | 681 self.top.quit() |
| 23547 | 682 elif (self.executing and self.interp.rpcclt and |
| 683 self.interp.rpcpid and hasattr(os, "kill")): | |
| 684 try: | |
| 685 from signal import SIGINT | |
| 686 except ImportError: | |
| 687 SIGINT = 2 | |
| 688 os.kill(self.interp.rpcpid, SIGINT) | |
| 689 else: | |
| 690 self.canceled = 1 | |
| 13975 | 691 return "break" |
| 692 | |
| 693 def eof_callback(self, event): | |
| 694 if self.executing and not self.reading: | |
| 695 return # Let the default binding (delete next char) take over | |
| 696 if not (self.text.compare("iomark", "==", "insert") and | |
| 697 self.text.compare("insert", "==", "end-1c")): | |
| 698 return # Let the default binding (delete next char) take over | |
| 699 if not self.executing: | |
| 700 self.resetoutput() | |
| 701 self.close() | |
| 702 else: | |
| 703 self.canceled = 0 | |
| 704 self.endoffile = 1 | |
| 705 self.top.quit() | |
| 706 return "break" | |
| 707 | |
| 708 def home_callback(self, event): | |
| 709 if event.state != 0 and event.keysym == "Home": | |
| 710 return # <Modifier-Home>; fall back to class binding | |
| 711 if self.text.compare("iomark", "<=", "insert") and \ | |
| 712 self.text.compare("insert linestart", "<=", "iomark"): | |
| 713 self.text.mark_set("insert", "iomark") | |
| 714 self.text.tag_remove("sel", "1.0", "end") | |
| 715 self.text.see("insert") | |
| 716 return "break" | |
| 717 | |
| 718 def linefeed_callback(self, event): | |
| 719 # Insert a linefeed without entering anything (still autoindented) | |
| 720 if self.reading: | |
| 721 self.text.insert("insert", "\n") | |
| 722 self.text.see("insert") | |
| 723 else: | |
| 724 self.auto.auto_indent(event) | |
| 725 return "break" | |
| 726 | |
| 727 def enter_callback(self, event): | |
| 728 if self.executing and not self.reading: | |
| 729 return # Let the default binding (insert '\n') take over | |
| 730 # If some text is selected, recall the selection | |
| 731 # (but only if this before the I/O mark) | |
| 732 try: | |
| 733 sel = self.text.get("sel.first", "sel.last") | |
| 734 if sel: | |
| 735 if self.text.compare("sel.last", "<=", "iomark"): | |
| 736 self.recall(sel) | |
| 737 return "break" | |
| 738 except: | |
| 739 pass | |
| 740 # If we're strictly before the line containing iomark, recall | |
| 741 # the current line, less a leading prompt, less leading or | |
| 742 # trailing whitespace | |
| 743 if self.text.compare("insert", "<", "iomark linestart"): | |
| 744 # Check if there's a relevant stdin range -- if so, use it | |
| 745 prev = self.text.tag_prevrange("stdin", "insert") | |
| 746 if prev and self.text.compare("insert", "<", prev[1]): | |
| 747 self.recall(self.text.get(prev[0], prev[1])) | |
| 748 return "break" | |
| 749 next = self.text.tag_nextrange("stdin", "insert") | |
| 750 if next and self.text.compare("insert lineend", ">=", next[0]): | |
| 751 self.recall(self.text.get(next[0], next[1])) | |
| 752 return "break" | |
| 753 # No stdin mark -- just get the current line | |
| 754 self.recall(self.text.get("insert linestart", "insert lineend")) | |
| 755 return "break" | |
| 756 # If we're in the current input and there's only whitespace | |
| 757 # beyond the cursor, erase that whitespace first | |
| 758 s = self.text.get("insert", "end-1c") | |
| 759 if s and not string.strip(s): | |
| 760 self.text.delete("insert", "end-1c") | |
| 761 # If we're in the current input before its last line, | |
| 762 # insert a newline right at the insert point | |
| 763 if self.text.compare("insert", "<", "end-1c linestart"): | |
| 764 self.auto.auto_indent(event) | |
| 765 return "break" | |
| 766 # We're in the last line; append a newline and submit it | |
| 767 self.text.mark_set("insert", "end-1c") | |
| 768 if self.reading: | |
| 769 self.text.insert("insert", "\n") | |
| 770 self.text.see("insert") | |
| 771 else: | |
| 772 self.auto.auto_indent(event) | |
| 773 self.text.tag_add("stdin", "iomark", "end-1c") | |
| 774 self.text.update_idletasks() | |
| 775 if self.reading: | |
| 776 self.top.quit() # Break out of recursive mainloop() in raw_input() | |
| 777 else: | |
| 778 self.runit() | |
| 779 return "break" | |
| 780 | |
| 781 def recall(self, s): | |
| 782 if self.history: | |
| 783 self.history.recall(s) | |
| 784 | |
| 785 def runit(self): | |
| 786 line = self.text.get("iomark", "end-1c") | |
| 787 # Strip off last newline and surrounding whitespace. | |
| 788 # (To allow you to hit return twice to end a statement.) | |
| 789 i = len(line) | |
| 790 while i > 0 and line[i-1] in " \t": | |
| 791 i = i-1 | |
| 792 if i > 0 and line[i-1] == "\n": | |
| 793 i = i-1 | |
| 794 while i > 0 and line[i-1] in " \t": | |
| 795 i = i-1 | |
| 796 line = line[:i] | |
| 797 more = self.interp.runsource(line) | |
| 798 if not more: | |
| 799 self.showprompt() | |
| 800 | |
| 801 def cancel_check(self, frame, what, args, | |
| 802 dooneevent=tkinter.dooneevent, | |
| 803 dontwait=tkinter.DONT_WAIT): | |
| 804 # Hack -- use the debugger hooks to be able to handle events | |
| 805 # and interrupt execution at any time. | |
| 806 # This slows execution down quite a bit, so you may want to | |
| 807 # disable this (by not calling settrace() in runcode() above) | |
| 808 # for full-bore (uninterruptable) speed. | |
| 809 # XXX This should become a user option. | |
| 810 if self.canceled: | |
| 811 return | |
| 812 dooneevent(dontwait) | |
| 813 if self.canceled: | |
| 814 self.canceled = 0 | |
| 815 raise KeyboardInterrupt | |
| 816 return self._cancel_check | |
| 817 | |
| 818 def open_stack_viewer(self, event=None): | |
| 23547 | 819 if self.interp.rpcclt: |
| 820 return self.interp.remote_stack_viewer() | |
| 13975 | 821 try: |
| 822 sys.last_traceback | |
| 823 except: | |
| 824 tkMessageBox.showerror("No stack trace", | |
| 825 "There is no stack trace yet.\n" | |
| 826 "(sys.last_traceback is not defined)", | |
| 827 master=self.text) | |
| 828 return | |
| 829 from StackViewer import StackBrowser | |
| 830 sv = StackBrowser(self.root, self.flist) | |
| 831 | |
| 832 def showprompt(self): | |
| 833 self.resetoutput() | |
| 834 try: | |
| 835 s = str(sys.ps1) | |
| 836 except: | |
| 837 s = "" | |
| 838 self.console.write(s) | |
| 839 self.text.mark_set("insert", "end-1c") | |
| 23547 | 840 self.set_line_and_column() |
| 13975 | 841 |
| 842 def resetoutput(self): | |
| 843 source = self.text.get("iomark", "end-1c") | |
| 844 if self.history: | |
| 845 self.history.history_store(source) | |
| 846 if self.text.get("end-2c") != "\n": | |
| 847 self.text.insert("end-1c", "\n") | |
| 848 self.text.mark_set("iomark", "end-1c") | |
| 23547 | 849 self.set_line_and_column() |
| 13975 | 850 sys.stdout.softspace = 0 |
| 851 | |
| 852 def write(self, s, tags=()): | |
| 853 self.text.mark_gravity("iomark", "right") | |
| 854 OutputWindow.write(self, s, tags, "iomark") | |
| 855 self.text.mark_gravity("iomark", "left") | |
| 856 if self.canceled: | |
| 857 self.canceled = 0 | |
| 858 raise KeyboardInterrupt | |
| 859 | |
| 860 class PseudoFile: | |
| 861 | |
| 862 def __init__(self, shell, tags): | |
| 863 self.shell = shell | |
| 864 self.tags = tags | |
| 23547 | 865 self.softspace = 0 |
| 13975 | 866 |
| 867 def write(self, s): | |
| 868 self.shell.write(s, self.tags) | |
| 869 | |
| 870 def writelines(self, l): | |
| 871 map(self.write, l) | |
| 872 | |
| 873 def flush(self): | |
| 874 pass | |
| 875 | |
| 876 def isatty(self): | |
| 877 return 1 | |
| 878 | |
| 879 usage_msg = """\ | |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
880 usage: idle.py [-c command] [-d] [-i] [-r script] [-s] [-t title] [arg] ... |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
881 |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
882 idle file(s) (without options) edit the file(s) |
| 13975 | 883 |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
884 -c cmd run the command in a shell |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
885 -d enable the debugger |
| 23547 | 886 -e edit mode; arguments are files to be edited |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
887 -i open an interactive shell |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
888 -i file(s) open a shell and also an editor window for each file |
| 23547 | 889 -r script use experimental remote (subprocess) execution feature |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
890 -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
891 -t title set title of shell window |
| 13975 | 892 |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
893 Remaining arguments are applied to the command (-c) or script (-r). |
| 13975 | 894 """ |
| 895 | |
| 896 class usageError: | |
| 897 def __init__(self, string): self.string = string | |
| 898 def __repr__(self): return self.string | |
| 899 | |
| 900 class main: | |
|
18613
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
901 def __init__(self, noshell=1): |
|
20306
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
902 |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
903 global flist, root |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
904 root = Tk(className="Idle") |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
905 fixwordbreaks(root) |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
906 root.withdraw() |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
907 flist = PyShellFileList(root) |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
908 |
|
22599
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
909 # the following causes lockups and silent failures when debugging |
|
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
910 # changes to EditorWindow.__init__ ; the console works fine for idle |
|
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
911 # debugging in any case, so disable this unnescesary stuff. |
|
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
912 #dbg=OnDemandOutputWindow(flist) |
|
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
913 #dbg.set_title('IDLE Debugging Messages') |
|
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
914 #sys.stdout = PseudoFile(dbg,['stdout']) |
|
194ed5e0dc8f
_finally_ tracked down and eliminated a major problem
Steven M. Gava <elguavas@python.net>
parents:
22111
diff
changeset
|
915 #sys.stderr = PseudoFile(dbg,['stderr']) |
|
20306
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
916 |
| 13975 | 917 try: |
| 918 self.server = protocol.Server(connection_hook = self.address_ok) | |
| 919 protocol.publish( 'IDLE', self.connect ) | |
|
18613
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
920 self.main(sys.argv[1:], noshell) |
| 13975 | 921 return |
| 922 except protocol.connectionLost: | |
| 923 try: | |
| 924 client = protocol.Client() | |
| 925 IDLE = client.getobject('IDLE') | |
| 926 if IDLE: | |
| 927 try: | |
| 928 IDLE.remote( sys.argv[1:] ) | |
| 929 except usageError, msg: | |
| 930 sys.stderr.write("Error: %s\n" % str(msg)) | |
| 931 sys.stderr.write(usage_msg) | |
| 932 return | |
| 933 except protocol.connectionLost: | |
| 934 pass | |
| 935 | |
|
20306
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
936 #maybe the following should be handled by a tkmessagebox for |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
937 #users who don't start idle from a console?? |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
938 print """\ |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
939 IDLE cannot run. |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
940 |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
941 IDLE needs to use a specific TCP/IP port (7454) in order to execute and |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
942 debug programs. IDLE is unable to bind to this port, and so cannot |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
943 start. Here are some possible causes of this problem: |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
944 |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
945 1. TCP/IP networking is not installed or not working on this computer |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
946 2. Another program is running that uses this port |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
947 3. Another copy of IDLE stopped responding but is still bound to the port |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
948 4. Personal firewall software is preventing IDLE from using this port |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
949 |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
950 IDLE makes and accepts connections only with this computer, and does not |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
951 communicate over the internet in any way. It's use of port 7454 should not |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
952 be a security risk on a single-user machine. |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
953 """ |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
954 dbg.owin.gotoline(1) |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
955 dbg.owin.remove_selection() |
|
1ca228e21a98
merged port binding error message patch
Steven M. Gava <elguavas@python.net>
parents:
18649
diff
changeset
|
956 root.mainloop() # wait for user to read message |
| 13975 | 957 |
| 958 def idle(self): | |
| 959 spawn.kill_zombies() | |
| 960 self.server.rpc_loop() | |
| 961 root.after(25, self.idle) | |
| 962 | |
| 963 # We permit connections from localhost only | |
| 964 def address_ok(self, addr): | |
| 965 return addr[0] == '127.0.0.1' | |
| 966 | |
| 967 def connect(self, client, addr): | |
| 968 return self | |
| 969 | |
| 970 def remote( self, argv ): | |
| 971 # xxx Should make this behavior match the behavior in main, or redo | |
| 972 # command line options entirely. | |
| 973 | |
| 974 try: | |
| 975 opts, args = getopt.getopt(argv, "c:deist:") | |
| 976 except getopt.error, msg: | |
| 977 raise usageError(msg) | |
| 978 | |
| 979 for filename in args: | |
| 980 flist.open(filename) | |
| 981 if not args: | |
| 982 flist.new() | |
| 983 | |
|
18613
6238a222b7cd
Add a script "idles" which opens a Python Shell window.
Kurt B. Kaiser <kbk@shore.net>
parents:
18586
diff
changeset
|
984 def main(self, argv, noshell): |
| 13975 | 985 cmd = None |
| 986 edit = 0 | |
| 987 debug = 0 | |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
988 interactive = 0 |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
989 script = None |
| 13975 | 990 startup = 0 |
| 23547 | 991 global use_subprocess |
| 13975 | 992 |
| 993 try: | |
| 23547 | 994 opts, args = getopt.getopt(sys.argv[1:], "c:deir:st:") |
| 13975 | 995 except getopt.error, msg: |
| 996 sys.stderr.write("Error: %s\n" % str(msg)) | |
| 997 sys.stderr.write(usage_msg) | |
| 998 sys.exit(2) | |
| 999 | |
| 1000 for o, a in opts: | |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1001 noshell = 0 # There are options, bring up a shell |
| 13975 | 1002 if o == '-c': |
| 1003 cmd = a | |
| 1004 if o == '-d': | |
| 1005 debug = 1 | |
| 23547 | 1006 if o == '-e': |
| 1007 edit = 1 | |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1008 if o == '-i': |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1009 interactive = 1 |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1010 if o == '-r': |
| 23547 | 1011 edit = 1 |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1012 script = a |
| 23547 | 1013 use_subprocess = 1 |
| 13975 | 1014 if o == '-s': |
| 1015 startup = 1 | |
| 1016 if o == '-t': | |
| 1017 PyShell.shell_title = a | |
| 1018 | |
| 1019 if noshell: edit=1 | |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1020 if interactive and args and args[0] != "-": edit = 1 |
| 13975 | 1021 |
| 1022 for i in range(len(sys.path)): | |
| 1023 sys.path[i] = os.path.abspath(sys.path[i]) | |
| 1024 | |
| 1025 pathx = [] | |
| 1026 if edit: | |
| 1027 for filename in args: | |
| 1028 pathx.append(os.path.dirname(filename)) | |
| 1029 elif args and args[0] != "-": | |
| 1030 pathx.append(os.path.dirname(args[0])) | |
| 1031 else: | |
| 1032 pathx.append(os.curdir) | |
| 1033 for dir in pathx: | |
| 1034 dir = os.path.abspath(dir) | |
| 1035 if not dir in sys.path: | |
| 1036 sys.path.insert(0, dir) | |
| 1037 | |
| 1038 if edit: | |
| 1039 for filename in args: | |
| 1040 flist.open(filename) | |
| 1041 if not args: | |
| 1042 flist.new() | |
|
18560
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
1043 else: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
1044 if cmd: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
1045 sys.argv = ["-c"] + args |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
1046 else: |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
1047 sys.argv = args or [""] |
|
12e7ad108229
cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
1048 |
| 13975 | 1049 if noshell: |
| 1050 flist.pyshell = None | |
| 1051 else: | |
| 1052 shell = PyShell(flist) | |
| 1053 interp = shell.interp | |
| 1054 flist.pyshell = shell | |
| 1055 | |
| 1056 if startup: | |
| 1057 filename = os.environ.get("IDLESTARTUP") or \ | |
| 1058 os.environ.get("PYTHONSTARTUP") | |
| 1059 if filename and os.path.isfile(filename): | |
| 1060 interp.execfile(filename) | |
| 1061 | |
| 1062 if debug: | |
| 1063 shell.open_debugger() | |
| 1064 if cmd: | |
| 1065 interp.execsource(cmd) | |
|
18649
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1066 elif script: |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1067 if os.path.isfile(script): |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1068 interp.execfile(script) |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1069 else: |
|
8aa63aea7269
Implement idle command interface as suggested by GvR [idle-dev] 16 July
Kurt B. Kaiser <kbk@shore.net>
parents:
18614
diff
changeset
|
1070 print "No script file: ", script |
| 13975 | 1071 shell.begin() |
| 1072 | |
| 1073 self.idle() | |
| 1074 root.mainloop() | |
| 1075 root.destroy() | |
| 1076 | |
| 1077 | |
| 1078 if __name__ == "__main__": | |
| 1079 main() |
