PyShell.py revision c569cfebcebd3d3c8cf77e6c8971a19c78ff7261
17aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#! /usr/bin/env python 27aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 37aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport os 46e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiserimport os.path 57aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport sys 67aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport string 77aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport getopt 87aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport re 95d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport socket 105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport time 11003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiserimport threading 125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport traceback 13628339807e76d075a610aa6dd963e702ef25afc8Kurt B. Kaiserimport types 147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport linecache 167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom code import InteractiveInterpreter 177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 182303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaisertry: 196634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl from Tkinter import * 202303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiserexcept ImportError: 216634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl print>>sys.__stderr__, "** IDLE can't import Tkinter. " \ 222303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser "Your Python may not be configured for Tk. **" 232303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser sys.exit(1) 246634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandlimport tkMessageBox 257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 26d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.EditorWindow import EditorWindow, fixwordbreaks 27d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.FileList import FileList 28d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.ColorDelegator import ColorDelegator 29d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.UndoDelegator import UndoDelegator 30d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.OutputWindow import OutputWindow 31d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.configHandler import idleConf 32d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import idlever 33d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import rpc 34d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import Debugger 35d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import RemoteDebugger 36d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import macosxSupport 375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 38b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_" 39013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserHOST = '127.0.0.1' # python execution server on localhost loopback 40013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserPORT = 0 # someday pass in host, port for remote debug capability 41b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser 42a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry: 43a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser from signal import SIGTERM 44a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError: 45a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser SIGTERM = 15 46a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser 4749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# Override warnings module to write to warning_stream. Initialize to send IDLE 4849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# internal warnings to the console. ScriptBinding.check_syntax() will 4949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# temporarily redirect the stream to the shell window to display warnings when 5049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# checking user's code. 5149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiserglobal warning_stream 5249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiserwarning_stream = sys.__stderr__ 535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teytry: 545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey import warnings 555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyexcept ImportError: 565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey pass 575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyelse: 58b76444b2fa39a99984ffa4bcfa9806fbb091594aBenjamin Peterson def idle_showwarning(message, category, filename, lineno, 59b76444b2fa39a99984ffa4bcfa9806fbb091594aBenjamin Peterson file=None, line=None): 60f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo if file is None: 61f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo file = warning_stream 6249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser try: 63f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo file.write(warnings.formatwarning(message, category, filename, 64b76444b2fa39a99984ffa4bcfa9806fbb091594aBenjamin Peterson lineno, file=file, line=line)) 6549a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser except IOError: 6649a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser pass ## file (probably __stderr__) is invalid, warning dropped. 675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey warnings.showwarning = idle_showwarning 68f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo def idle_formatwarning(message, category, filename, lineno, line=None): 6949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser """Format warnings the IDLE way""" 7049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s = "\nWarning (from warnings module):\n" 7149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s += ' File \"%s\", line %s\n' % (filename, lineno) 72f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo if line is None: 73f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo line = linecache.getline(filename, lineno) 74f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo line = line.strip() 7549a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser if line: 7649a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s += " %s\n" % line 7749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s += "%s: %s\n>>> " % (category.__name__, message) 7849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser return s 7949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser warnings.formatwarning = idle_formatwarning 805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 81f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiserdef extended_linecache_checkcache(filename=None, 82f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser orig_checkcache=linecache.checkcache): 8345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser """Extend linecache.checkcache to preserve the <pyshell#...> entries 8445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 85f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser Rather than repeating the linecache code, patch it to save the 86f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser <pyshell#...> entries, call the original linecache.checkcache() 87f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo (skipping them), and then restore the saved entries. 88f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser 89f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser orig_checkcache is bound at definition time to the original 90f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser method, allowing it to be patched. 9145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser """ 927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer cache = linecache.cache 937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer save = {} 94f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo for key in list(cache): 95f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo if key[:1] + key[-1:] == '<>': 96f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo save[key] = cache.pop(key) 97f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo orig_checkcache(filename) 987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer cache.update(save) 996655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 100818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache(): 101818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache 1027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 1047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow): 105183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser "Regular text edit window in IDLE, supports breakpoints" 10645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 1077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, *args): 10845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints = [] 109931237e2e66975c54e2ac6c5e503ee2992a22bcfRaymond Hettinger EditorWindow.__init__(self, *args) 1107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here) 11145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here) 1127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind("<<open-python-shell>>", self.flist.open_shell) 1137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 114bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(), 115bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser 'breakpoints.lst') 116a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey # whenever a file is changed, restore breakpoints 117a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey if self.io.filename: self.restore_file_breaks() 118bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser def filename_changed_hook(old_hook=self.io.filename_change_hook, 119bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self=self): 120a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.restore_file_breaks() 121a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey old_hook() 122a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.io.set_filename_change_hook(filename_changed_hook) 123a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 12445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"), 12545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser ("Clear Breakpoint", "<<clear-breakpoint-here>>")] 1267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 127a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def set_breakpoint(self, lineno): 12845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text = self.text 12945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser filename = self.io.filename 130a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1)) 13145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 13245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser i = self.breakpoints.index(lineno) 133a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey except ValueError: # only add if missing, i.e. do once 13445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints.append(lineno) 13545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: # update the subprocess debugger 13645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.flist.pyshell.interp.debugger 13745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.set_breakpoint_here(filename, lineno) 13845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: # but debugger may not be active right now.... 13945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 1407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 141a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def set_breakpoint_here(self, event=None): 142a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text = self.text 143a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey filename = self.io.filename 144a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey if not filename: 145a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text.bell() 146a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey return 147a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey lineno = int(float(text.index("insert"))) 148a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.set_breakpoint(lineno) 149a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 150669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser def clear_breakpoint_here(self, event=None): 15145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text = self.text 15245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser filename = self.io.filename 15345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if not filename: 15445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.bell() 155669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser return 15645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser lineno = int(float(text.index("insert"))) 15745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 15845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints.remove(lineno) 15945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: 16045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 16145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.tag_remove("BREAK", "insert linestart",\ 16245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser "insert lineend +1char") 16345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 16445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.flist.pyshell.interp.debugger 16545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.clear_breakpoint_here(filename, lineno) 16645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: 16745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 16845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 16945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def clear_file_breaks(self): 17045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if self.breakpoints: 17145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text = self.text 17245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser filename = self.io.filename 17345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if not filename: 17445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.bell() 17545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser return 17645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints = [] 17745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.tag_remove("BREAK", "1.0", END) 17845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 17945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.flist.pyshell.interp.debugger 18045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.clear_file_breaks(filename) 18145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: 18245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 18345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 184a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def store_file_breaks(self): 185bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser "Save breakpoints when file is saved" 186bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # XXX 13 Dec 2002 KBK Currently the file must be saved before it can 187bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # be run. The breaks are saved at that time. If we introduce 188bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # a temporary file save feature the save breaks functionality 189bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # needs to be re-verified, since the breaks at the time the 190bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # temp file is created may differ from the breaks at the last 1917f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # permanent save of the file. Currently, a break introduced 1927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # after a save will be effective, but not persistent. 1937f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # This is necessary to keep the saved breaks synched with the 1947f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # saved file. 195bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # 196bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # Breakpoints are set as tagged ranges in the text. Certain 197bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # kinds of edits cause these ranges to be deleted: Inserting 198bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # or deleting a line just before a breakpoint, and certain 199bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # deletions prior to a breakpoint. These issues need to be 200bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # investigated and understood. It's not clear if they are 201bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # Tk issues or IDLE issues, or whether they can actually 202bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # be fixed. Since a modified file has to be saved before it is 203bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # run, and since self.breakpoints (from which the subprocess 204bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # debugger is loaded) is updated during the save, the visible 205bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # breaks stay synched with the subprocess even if one of these 206bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # unexpected breakpoint deletions occurs. 207bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser breaks = self.breakpoints 208bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser filename = self.io.filename 209a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey try: 210bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = open(self.breakpointPath,"r").readlines() 211a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey except IOError: 212bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = [] 213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser new_file = open(self.breakpointPath,"w") 214a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey for line in lines: 215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser if not line.startswith(filename + '='): 216a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey new_file.write(line) 217bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self.update_breakpoints() 218bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser breaks = self.breakpoints 219bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser if breaks: 220bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser new_file.write(filename + '=' + str(breaks) + '\n') 221a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey new_file.close() 222a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 223a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def restore_file_breaks(self): 224a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.text.update() # this enables setting "BREAK" tags to be visible 225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser filename = self.io.filename 226bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser if filename is None: 227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser return 22869371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey if os.path.isfile(self.breakpointPath): 229bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = open(self.breakpointPath,"r").readlines() 23069371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey for line in lines: 231bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser if line.startswith(filename + '='): 2326655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser breakpoint_linenumbers = eval(line[len(filename)+1:]) 23369371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey for breakpoint_linenumber in breakpoint_linenumbers: 23469371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey self.set_breakpoint(breakpoint_linenumber) 235a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 236bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser def update_breakpoints(self): 237bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser "Retrieves all the breakpoints in the current window" 238a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text = self.text 239bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser ranges = text.tag_ranges("BREAK") 240bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser linenumber_list = self.ranges_to_linenumbers(ranges) 241bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self.breakpoints = linenumber_list 242bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser 243bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser def ranges_to_linenumbers(self, ranges): 244bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = [] 245bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser for index in range(0, len(ranges), 2): 246bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lineno = int(float(ranges[index])) 247bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser end = int(float(ranges[index+1])) 248bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser while lineno < end: 249bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines.append(lineno) 250bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lineno += 1 251bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser return lines 252bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser 25311220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently 254bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# def saved_change_hook(self): 255bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# "Extend base method - clear breaks if module is modified" 256bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# if not self.get_saved(): 257bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# self.clear_file_breaks() 258bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# EditorWindow.saved_change_hook(self) 25945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 26045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def _close(self): 26145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser "Extend base method - clear breaks when module is closed" 26245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.clear_file_breaks() 26345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser EditorWindow._close(self) 2646655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 2657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList): 267183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser "Extend base class: IDLE supports a shell and breakpoints" 2687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 269183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser # override FileList's class variable, instances return PyShellEditorWindow 270183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser # instead of EditorWindow when new edit windows are created. 2717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer EditorWindow = PyShellEditorWindow 2727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pyshell = None 2747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_shell(self, event=None): 2767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.pyshell: 277183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser self.pyshell.top.wakeup() 2787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 2797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.pyshell = PyShell(self) 280af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if self.pyshell: 281af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if not self.pyshell.begin(): 282af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 2837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.pyshell 2847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator): 28783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class: colorizer for the shell window itself" 2886655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 289b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava def __init__(self): 290b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava ColorDelegator.__init__(self) 291b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava self.LoadTagDefs() 2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def recolorize_main(self): 2947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tag_remove("TODO", "1.0", "iomark") 2957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tag_add("SYNC", "1.0", "iomark") 2967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ColorDelegator.recolorize_main(self) 2976655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 298b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava def LoadTagDefs(self): 299b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava ColorDelegator.LoadTagDefs(self) 300b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava theme = idleConf.GetOption('main','Theme','name') 301b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava self.tagdefs.update({ 302b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "stdin": {'background':None,'foreground':None}, 303b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "stdout": idleConf.GetHighlight(theme, "stdout"), 304b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "stderr": idleConf.GetHighlight(theme, "stderr"), 305b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "console": idleConf.GetHighlight(theme, "console"), 306b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava }) 3077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator): 30983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class: forbid insert/delete before the I/O mark" 3107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def insert(self, index, chars, tags=None): 3127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 3137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.delegate.compare(index, "<", "iomark"): 3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.delegate.bell() 3157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 3167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except TclError: 3177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 3187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer UndoDelegator.insert(self, index, chars, tags) 3197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def delete(self, index1, index2=None): 3217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 3227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.delegate.compare(index1, "<", "iomark"): 3237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.delegate.bell() 3247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 3257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except TclError: 3267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 3277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer UndoDelegator.delete(self, index1, index2) 3287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 32967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser 33067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient): 33167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser 33267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser def handle_EOF(self): 33367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser "Override the base class - just re-raise EOFError" 33467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser raise EOFError 33567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser 3368d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser 3377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter): 3387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, tkconsole): 3407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole = tkconsole 3417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer locals = sys.modules['__main__'].__dict__ 3427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer InteractiveInterpreter.__init__(self, locals=locals) 34394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = None 3446f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser self.restarting = False 345013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.subprocess_arglist = None 346013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.port = PORT 3477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey rpcclt = None 3495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey rpcpid = None 3505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 3516655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser def spawn_subprocess(self): 352c8a730bf72b1c95651a8a39766bf56635956a2e0Florent Xicluna if self.subprocess_arglist is None: 353013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.subprocess_arglist = self.build_subprocess_arglist() 35462df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser args = self.subprocess_arglist 355b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) 35663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser 357f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds def build_subprocess_arglist(self): 358013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser assert (self.port!=0), ( 359013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "Socket should have been assigned a port number.") 3602398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds w = ['-W' + s for s in sys.warnoptions] 361d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl if 1/2 > 0: # account for new division 362d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl w.append('-Qnew') 3632398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds # Maybe IDLE is installed and is being accessed via sys.path, 3642398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds # or maybe it's not installed and the idle.py script is being 3652398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds # run from the IDLE source directory. 36662df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc', 36762df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser default=False, type='bool') 3682398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds if __name__ == 'idlelib.PyShell': 36970a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) 370f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds else: 37170a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald command = "__import__('run').main(%r)" % (del_exitf,) 372b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser if sys.platform[:3] == 'win' and ' ' in sys.executable: 373b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser # handle embedded space in path by quoting the argument 374b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser decorated_exec = '"%s"' % sys.executable 375b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser else: 376b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser decorated_exec = sys.executable 377b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser return [decorated_exec] + w + ["-c", command, str(self.port)] 378f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds 37963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser def start_subprocess(self): 380013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser addr = (HOST, self.port) 381013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # GUI makes several attempts to acquire socket, listens for connection 3825db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser for i in range(3): 3835d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey time.sleep(i) 3845d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey try: 38567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.rpcclt = MyRPCClient(addr) 3865d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey break 3875d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey except socket.error, err: 388af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser pass 3895d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey else: 390af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.display_port_binding_error() 391af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 392013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # if PORT was 0, system will assign an 'ephemeral' port. Find it out: 393013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.port = self.rpcclt.listening_sock.getsockname()[1] 394013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # if PORT was not 0, probably working with a remote execution server 395013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser if PORT != 0: 396013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # To allow reconnection within the 2MSL wait (cf. Stevens TCP 397013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic 398013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # on Windows since the implementation allows two active sockets on 399013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # the same address! 400013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, 401013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser socket.SO_REUSEADDR, 1) 402013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.spawn_subprocess() 403013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser #time.sleep(20) # test to simulate GUI not accepting connection 404b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser # Accept the connection from the Python execution server 405af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.listening_sock.settimeout(10) 406af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser try: 407af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.accept() 408af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser except socket.timeout, err: 409af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.display_no_subprocess_error() 410af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 411969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser self.rpcclt.register("stdin", self.tkconsole) 412969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser self.rpcclt.register("stdout", self.tkconsole.stdout) 413969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser self.rpcclt.register("stderr", self.tkconsole.stderr) 4145d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.rpcclt.register("flist", self.tkconsole.flist) 4158cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser self.rpcclt.register("linecache", linecache) 4169f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser self.rpcclt.register("interp", self) 417f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser self.transfer_path() 4185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.poll_subprocess() 419af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return self.rpcclt 4205d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 42163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser def restart_subprocess(self): 4226f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser if self.restarting: 423af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return self.rpcclt 4246f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser self.restarting = True 42563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser # close only the subprocess debugger 42645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.getdebugger() 42745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if debug: 428003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser try: 4299ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser # Only close subprocess debugger, don't unregister gui_adap! 430003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser RemoteDebugger.close_subprocess_debugger(self.rpcclt) 431003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser except: 432003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser pass 433003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser # Kill subprocess, spawn a new one, accept connection. 434a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt.close() 435a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.unix_terminate() 4367f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser console = self.tkconsole 4376f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser was_executing = console.executing 4387f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser console.executing = False 43963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser self.spawn_subprocess() 440af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser try: 441af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.accept() 442af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser except socket.timeout, err: 443af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.display_no_subprocess_error() 444af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 445f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser self.transfer_path() 4461061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser # annotate restart in shell window and mark it 4474cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser console.text.delete("iomark", "end-1c") 4486f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser if was_executing: 4496f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser console.write('\n') 4506f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser console.showprompt() 4511061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser halfbar = ((int(console.width) - 16) // 2) * '=' 4521061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser console.write(halfbar + ' RESTART ' + halfbar) 4531061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser console.text.mark_set("restart", "end-1c") 4541061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser console.text.mark_gravity("restart", "left") 4557f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser console.showprompt() 456003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser # restart subprocess debugger 45745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if debug: 4589ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser # Restarted debugger connects to current instance of debug GUI 45963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt) 46045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser # reload remote debugger breakpoints for all PyShellEditWindows 46145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.load_breakpoints() 4626f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser self.restarting = False 463af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return self.rpcclt 46445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 465003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser def __request_interrupt(self): 466a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt.remotecall("exec", "interrupt_the_server", (), {}) 467003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser 468003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser def interrupt_subprocess(self): 469a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser threading.Thread(target=self.__request_interrupt).start() 470003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser 471a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser def kill_subprocess(self): 472af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser try: 473af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.close() 474af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser except AttributeError: # no socket 475af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser pass 476a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.unix_terminate() 477a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.tkconsole.executing = False 478a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt = None 47911c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser 480a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser def unix_terminate(self): 481a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser "UNIX: make sure subprocess is terminated and collect status" 482a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser if hasattr(os, 'kill'): 483a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser try: 484a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser os.kill(self.rpcpid, SIGTERM) 485a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser except OSError: 486a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser # process already terminated: 487a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser return 488a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser else: 489a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser try: 490a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser os.waitpid(self.rpcpid, 0) 491a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser except OSError: 492a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser return 49311c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser 494f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser def transfer_path(self): 495f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser self.runcommand("""if 1: 496f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser import sys as _sys 49770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald _sys.path = %r 498f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser del _sys 49970a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald \n""" % (sys.path,)) 500f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 5015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey active_seq = None 5025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 5035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey def poll_subprocess(self): 5045d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey clt = self.rpcclt 5055d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if clt is None: 5065d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 507003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser try: 508a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser response = clt.pollresponse(self.active_seq, wait=0.05) 509a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser except (EOFError, IOError, KeyboardInterrupt): 510a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser # lost connection or subprocess terminated itself, restart 511a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser # [the KBI is from rpc.SocketIO.handle_EOF()] 51267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser if self.tkconsole.closing: 51367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser return 514003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser response = None 515003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.restart_subprocess() 5165d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if response: 5175d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.tkconsole.resetoutput() 5185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.active_seq = None 5195d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey how, what = response 520bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser console = self.tkconsole.console 5215d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if how == "OK": 5225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if what is not None: 52370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald print >>console, repr(what) 5245d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey elif how == "EXCEPTION": 5255d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): 5265d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.remote_stack_viewer() 5275d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey elif how == "ERROR": 5280930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n" 5290930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser print >>sys.__stderr__, errmsg, what 530bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser print >>console, errmsg, what 531bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser # we received a response to the currently active seq number: 532d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser try: 533d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser self.tkconsole.endexecuting() 534d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser except AttributeError: # shell may have closed 535d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser pass 53688957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser # Reschedule myself 53788957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser if not self.tkconsole.closing: 53888957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser self.tkconsole.text.after(self.tkconsole.pollinterval, 53988957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser self.poll_subprocess) 5405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 54145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debugger = None 54245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 54345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def setdebugger(self, debugger): 54445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.debugger = debugger 54545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 54645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def getdebugger(self): 54745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser return self.debugger 54845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 5499f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser def open_remote_stack_viewer(self): 5509f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser """Initiate the remote stack viewer from a separate thread. 5519f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser 5529f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser This method is called from the subprocess, and by returning from this 5539f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser method we allow the subprocess to unblock. After a bit the shell 5549f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser requests the subprocess to open the remote stack viewer which returns a 555c569cfebcebd3d3c8cf77e6c8971a19c78ff7261Ezio Melotti static object looking at the last exception. It is queried through 5569f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser the RPC mechanism. 5579f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser 5589f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser """ 5599f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser self.tkconsole.text.after(300, self.remote_stack_viewer) 5609f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser return 5619f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser 5625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey def remote_stack_viewer(self): 563d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import RemoteObjectBrowser 564a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {}) 5655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if oid is None: 5665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.tkconsole.root.bell() 5675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 5685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) 569d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib.TreeWidget import ScrolledCanvas, TreeNode 5705d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey top = Toplevel(self.tkconsole.root) 57173360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser theme = idleConf.GetOption('main','Theme','name') 57273360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser background = idleConf.GetHighlight(theme, 'normal')['background'] 57373360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser sc = ScrolledCanvas(top, bg=background, highlightthickness=0) 5745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sc.frame.pack(expand=1, fill="both") 5755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey node = TreeNode(sc.canvas, None, item) 5765d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey node.expand() 5775d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey # XXX Should GC the remote tree when closing the window 5785d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 5797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer gid = 0 5807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 5817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def execsource(self, source): 58283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Like runsource() but assumes complete exec source" 5837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.stuffsource(source) 5847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.execfile(filename, source) 5857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 5867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def execfile(self, filename, source=None): 58783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Execute an existing file" 5887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if source is None: 5897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer source = open(filename, "r").read() 5907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 5917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer code = compile(source, filename, "exec") 5927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except (OverflowError, SyntaxError): 5937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole.resetoutput() 5947f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser tkerr = self.tkconsole.stderr 5957f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser print>>tkerr, '*** Error in script or command!\n' 5967f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser print>>tkerr, 'Traceback (most recent call last):' 5977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer InteractiveInterpreter.showsyntaxerror(self, filename) 5986e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.tkconsole.showprompt() 5997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 6007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.runcode(code) 6017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def runsource(self, source): 60383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class method: Stuff the source in the line cache first" 6047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.stuffsource(source) 6057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.more = 0 60694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = warnings.filters[:] 60794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser warnings.filterwarnings(action="error", category=SyntaxWarning) 608837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser if isinstance(source, types.UnicodeType): 609d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import IOBinding 610837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser try: 611837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser source = source.encode(IOBinding.encoding) 612837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser except UnicodeError: 613837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser self.tkconsole.resetoutput() 614cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser self.write("Unsupported characters in input\n") 615837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return 61694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser try: 617935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser # InteractiveInterpreter.runsource() calls its runcode() method, 618935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser # which is overridden (see below) 61994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser return InteractiveInterpreter.runsource(self, source, filename) 62094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser finally: 62194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser if self.save_warnings_filters is not None: 62294bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser warnings.filters[:] = self.save_warnings_filters 62394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = None 6247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def stuffsource(self, source): 62683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Stuff source in the filename cache" 6277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = "<pyshell#%d>" % self.gid 6287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.gid = self.gid + 1 629837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser lines = source.split("\n") 6307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer linecache.cache[filename] = len(source)+1, 0, lines, filename 6317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return filename 6326655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 63311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser def prepend_syspath(self, filename): 63411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser "Prepend sys.path with file's directory if not already included" 63511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser self.runcommand("""if 1: 63670a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald _filename = %r 63711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser import sys as _sys 63811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser from os.path import dirname as _dirname 63911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser _dir = _dirname(_filename) 64011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser if not _dir in _sys.path: 64111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser _sys.path.insert(0, _dir) 64211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser del _filename, _sys, _dirname, _dir 64370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald \n""" % (filename,)) 64411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser 6457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def showsyntaxerror(self, filename=None): 64683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser """Extend base class method: Add Colorizing 64783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser 64883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser Color the offending position instead of printing it and pointing at it 64983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser with a caret. 65083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser 65183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser """ 6527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.tkconsole.text 6537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer stuff = self.unpackerror() 6546e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser if stuff: 6556e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser msg, lineno, offset, line = stuff 6566e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser if lineno == 1: 6576e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser pos = "iomark + %d chars" % (offset-1) 6586e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser else: 6596e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser pos = "iomark linestart + %d lines + %d chars" % \ 6606e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser (lineno-1, offset-1) 6616e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser text.tag_add("ERROR", pos) 6626e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser text.see(pos) 6636e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser char = text.get(pos) 6646e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser if char and char in IDENTCHARS: 6656e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser text.tag_add("ERROR", pos + " wordstart", pos) 6667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole.resetoutput() 6676e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.write("SyntaxError: %s\n" % str(msg)) 6687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 6696e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.tkconsole.resetoutput() 6706e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser InteractiveInterpreter.showsyntaxerror(self, filename) 6716e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.tkconsole.showprompt() 6727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def unpackerror(self): 6747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer type, value, tb = sys.exc_info() 6757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ok = type is SyntaxError 6767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if ok: 6777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 6787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer msg, (dummy_filename, lineno, offset, line) = value 679bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser if not offset: 680bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser offset = 0 6817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 6827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ok = 0 6837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if ok: 6847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return msg, lineno, offset, line 6857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 6867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return None 6877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def showtraceback(self): 68983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class method to reset output properly" 6907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole.resetoutput() 6917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.checklinecache() 6927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer InteractiveInterpreter.showtraceback(self) 6935d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): 6945d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.tkconsole.open_stack_viewer() 6957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def checklinecache(self): 6977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer c = linecache.cache 6987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for key in c.keys(): 6997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if key[:1] + key[-1:] != "<>": 7007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer del c[key] 7017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey def runcommand(self, code): 70383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Run the code without invoking the debugger" 7045d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey # The code better not raise an exception! 7055d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.executing: 706f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz self.display_executing_dialog() 7075d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 0 7085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.rpcclt: 709a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt.remotequeue("exec", "runcode", (code,), {}) 7105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey else: 7115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey exec code in self.locals 7125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 1 7135d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 7147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def runcode(self, code): 71583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Override base class method" 7165d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.executing: 717003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.interp.restart_subprocess() 7185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.checklinecache() 71994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser if self.save_warnings_filters is not None: 72094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser warnings.filters[:] = self.save_warnings_filters 72194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = None 7227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer debugger = self.debugger 7237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 7247f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.tkconsole.beginexecuting() 725dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if not debugger and self.rpcclt is not None: 726dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.active_seq = self.rpcclt.asyncqueue("exec", "runcode", 727dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser (code,), {}) 728dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser elif debugger: 729dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser debugger.run(code, self.locals) 730dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 731dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser exec code in self.locals 732dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser except SystemExit: 733dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if not self.tkconsole.closing: 734dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if tkMessageBox.askyesno( 735dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser "Exit?", 736dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser "Do you want to exit altogether?", 737dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser default="yes", 738dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser master=self.tkconsole.text): 739f137e1df2c02f5782c5b0f18a2b3b649f255f63aKurt B. Kaiser raise 740dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 741dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.showtraceback() 742dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 743dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser raise 744dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser except: 745dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if use_subprocess: 746dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser print >>self.tkconsole.stderr, \ 747dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser "IDLE internal error in runcode()" 7487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showtraceback() 749dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.tkconsole.endexecuting() 750dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 751dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if self.tkconsole.canceled: 752dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.tkconsole.canceled = False 753dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser print >>self.tkconsole.stderr, "KeyboardInterrupt" 754dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 755dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.showtraceback() 7567f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser finally: 7577f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if not use_subprocess: 758d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser try: 759d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser self.tkconsole.endexecuting() 760d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser except AttributeError: # shell may have closed 761d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser pass 7627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def write(self, s): 76483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Override base class method" 7657f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.tkconsole.stderr.write(s) 7667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 767af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser def display_port_binding_error(self): 768af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser tkMessageBox.showerror( 769af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "Port Binding Error", 770013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "IDLE can't bind to a TCP/IP port, which is necessary to " 771013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "communicate with its Python execution server. This might be " 772013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "because no networking is installed on this computer. " 773013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "Run IDLE with the -n command line switch to start without a " 774013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "subprocess and refer to Help/IDLE Help 'Running without a " 775013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "subprocess' for further details.", 776af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser master=self.tkconsole.text) 777af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 778af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser def display_no_subprocess_error(self): 779af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser tkMessageBox.showerror( 780af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "Subprocess Startup Error", 781af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "IDLE's subprocess didn't make connection. Either IDLE can't " 782af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "start a subprocess or personal firewall software is blocking " 783af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "the connection.", 784af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser master=self.tkconsole.text) 785af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 786af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser def display_executing_dialog(self): 787af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser tkMessageBox.showerror( 788af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "Already executing", 789af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "The Python Shell window is already executing a command; " 790af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "please wait until it is finished.", 791af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser master=self.tkconsole.text) 792af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 793af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 7947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow): 7957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer shell_title = "Python Shell" 7977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Override classes 7997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ColorDelegator = ModifiedColorDelegator 8007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer UndoDelegator = ModifiedUndoDelegator 8017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 802f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # Override menus 803dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser menu_specs = [ 804dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("file", "_File"), 805dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("edit", "_Edit"), 8064cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser ("debug", "_Debug"), 8071061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser ("options", "_Options"), 808dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("windows", "_Windows"), 809dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("help", "_Help"), 810dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ] 8117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 81219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren if macosxSupport.runningAsOSXApp(): 81319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren del menu_specs[-3] 81419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren menu_specs[-2] = ("windows", "_Window") 81519302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 81619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 8177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # New classes 818d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib.IdleHistory import History 8197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, flist=None): 8218f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser if use_subprocess: 82267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser ms = self.menu_specs 82367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser if ms[2][0] != "shell": 8247ae354846fff616746eeba6d27ccd5c175591caeKurt B. Kaiser ms.insert(2, ("shell", "She_ll")) 8257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.interp = ModifiedInterpreter(self) 8267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if flist is None: 8277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root = Tk() 8287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer fixwordbreaks(root) 8297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.withdraw() 8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist = PyShellFileList(root) 8315afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer OutputWindow.__init__(self, flist, None, None) 8335afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8346af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser## self.config(usetabs=1, indentwidth=8, context_use_ps1=1) 8356af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser self.usetabs = True 8366af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser # indentwidth must be 8 when using tabs. See note in EditorWindow: 8376af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser self.indentwidth = 8 8386af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser self.context_use_ps1 = True 8395afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 8417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.configure(wrap="char") 8427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<newline-and-indent>>", self.enter_callback) 8437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<plain-newline-and-indent>>", self.linefeed_callback) 8447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<interrupt-execution>>", self.cancel_callback) 8457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<end-of-file>>", self.eof_callback) 8467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<open-stack-viewer>>", self.open_stack_viewer) 84757bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser text.bind("<<toggle-debugger>>", self.toggle_debugger) 8487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer) 8498f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser if use_subprocess: 8508f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser text.bind("<<view-restart>>", self.view_restart_mark) 8518f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser text.bind("<<restart-shell>>", self.restart_shell) 8525afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.save_stdout = sys.stdout 8547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.save_stderr = sys.stderr 8557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.save_stdin = sys.stdin 856d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import IOBinding 857bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis self.stdout = PseudoFile(self, "stdout", IOBinding.encoding) 858bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis self.stderr = PseudoFile(self, "stderr", IOBinding.encoding) 859bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis self.console = PseudoFile(self, "console", IOBinding.encoding) 8605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if not use_subprocess: 8615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.stdout = self.stdout 8625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.stderr = self.stderr 8635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.stdin = self 8645afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.history = self.History(self.text) 8665afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 86788957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser self.pollinterval = 50 # millisec 8685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 8694d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser def get_standard_extension_names(self): 8704d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser return idleConf.GetExtensions(shell_only=True) 8714d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser 872003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser reading = False 873003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser executing = False 874003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser canceled = False 875003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser endoffile = False 876003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser closing = False 8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 87849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser def set_warning_stream(self, stream): 879d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro global warning_stream 880d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro warning_stream = stream 88149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser 88249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser def get_warning_stream(self): 88349a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser return warning_stream 88449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser 8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def toggle_debugger(self, event=None): 8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing: 8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror("Don't debug now", 8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "You can only toggle the debugger when idle", 8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.text) 8907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.set_debugger_indicator() 8917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 8927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 8937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db = self.interp.getdebugger() 8947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if db: 8957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close_debugger() 8967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 8977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.open_debugger() 8987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_debugger_indicator(self): 9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db = self.interp.getdebugger() 9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.setvar("<<toggle-debugger>>", not not db) 9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9031061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser def toggle_jit_stack_viewer(self, event=None): 9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass # All we need is the variable 9057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close_debugger(self): 9077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db = self.interp.getdebugger() 9087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if db: 9097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.interp.setdebugger(None) 9107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db.close() 911ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser if self.interp.rpcclt: 912ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser RemoteDebugger.close_remote_debugger(self.interp.rpcclt) 9137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 9147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.console.write("[DEBUG OFF]\n") 9157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.ps1 = ">>> " 9167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showprompt() 9177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.set_debugger_indicator() 9187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_debugger(self): 9205d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.interp.rpcclt: 9217f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, 9227f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self) 9237f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser else: 9247f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser dbg_gui = Debugger.Debugger(self) 9257f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.interp.setdebugger(dbg_gui) 9267f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser dbg_gui.load_breakpoints() 9275d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.ps1 = "[DEBUG ON]\n>>> " 9285d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.showprompt() 9295d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.set_debugger_indicator() 9305d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 9317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def beginexecuting(self): 932ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser "Helper for ModifiedInterpreter" 9337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 9347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.executing = 1 9357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def endexecuting(self): 93783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Helper for ModifiedInterpreter" 9387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.executing = 0 9397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 9405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.showprompt() 9417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close(self): 94383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend EditorWindow.close()" 9447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing: 945003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser response = tkMessageBox.askokcancel( 9467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "Kill?", 947003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser "The program is still running!\n Do you want to kill it?", 9487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer default="ok", 9497f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser parent=self.text) 9505b63acd31e0e40c1a9a9e9762905b0054ff37994Benjamin Peterson if response is False: 9517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "cancel" 9525c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if self.reading: 9535c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.top.quit() 9545c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.canceled = True 95567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.closing = True 95667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser # Wait for poll_subprocess() rescheduling to stop 95767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.text.after(2 * self.pollinterval, self.close2) 95888957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser 95988957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser def close2(self): 96088957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser return EditorWindow.close(self) 9617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def _close(self): 96383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend EditorWindow._close(), shut down debugger and execution server" 9647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close_debugger() 9657f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if use_subprocess: 9667f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.interp.kill_subprocess() 9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Restore std streams 9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stdout = self.save_stdout 9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stderr = self.save_stderr 9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stdin = self.save_stdin 9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Break cycles 9727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.interp = None 9737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.console = None 9747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist.pyshell = None 9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.history = None 97683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser EditorWindow._close(self) 9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def ispythonsource(self, filename): 97983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Override EditorWindow method: never remove the colorizer" 980837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return True 9817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def short_title(self): 9837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.shell_title 9847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 98594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser COPYRIGHT = \ 9868f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser 'Type "copyright", "credits" or "license()" for more information.' 98794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser 9887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def begin(self): 9897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 9907f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if use_subprocess: 9917f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser nosub = '' 992af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser client = self.interp.start_subprocess() 993af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if not client: 994af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.close() 9957663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser return False 9967f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser else: 9977f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser nosub = "==== No Subprocess ====" 998bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger self.write("Python %s on %s\n%s\n%s" % 999bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger (sys.version, sys.platform, self.COPYRIGHT, nosub)) 10007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showprompt() 10016634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl import Tkinter 10026634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl Tkinter._default_root = None # 03Jan04 KBK What's this? 10037663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser return True 10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def readline(self): 10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer save = self.reading 10077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.reading = 1 10095c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.top.mainloop() # nested mainloop() 10107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer finally: 10117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.reading = save 10127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = self.text.get("iomark", "end-1c") 10135c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if len(line) == 0: # may be EOF if we quit our mainloop with Ctrl-C 10145c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser line = "\n" 1015bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis if isinstance(line, unicode): 1016d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import IOBinding 1017bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis try: 1018bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis line = line.encode(IOBinding.encoding) 1019bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis except UnicodeError: 1020bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis pass 10217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 10227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.canceled: 10237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 10245c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if not use_subprocess: 10255c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser raise KeyboardInterrupt 10267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.endoffile: 10277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.endoffile = 0 10285c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser line = "" 10297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return line 10307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def isatty(self): 1032837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return True 10337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1034003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser def cancel_callback(self, event=None): 10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 10367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("sel.first", "!=", "sel.last"): 10377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Active selection -- always use default binding 10387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 10407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not (self.executing or self.reading): 10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 10427f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.interp.write("KeyboardInterrupt\n") 10437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showprompt() 10447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.endoffile = 0 1046003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.canceled = 1 10475c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if (self.executing and self.interp.rpcclt): 104867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser if self.interp.getdebugger(): 104967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.interp.restart_subprocess() 105067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser else: 105167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.interp.interrupt_subprocess() 10525c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if self.reading: 10535c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.top.quit() # exit the nested mainloop() in readline() 10547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def eof_callback(self, event): 10577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing and not self.reading: 10587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Let the default binding (delete next char) take over 10597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not (self.text.compare("iomark", "==", "insert") and 10607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.compare("insert", "==", "end-1c")): 10617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Let the default binding (delete next char) take over 10627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not self.executing: 10637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 10647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close() 10657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 10667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 10677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.endoffile = 1 10687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.quit() 10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def linefeed_callback(self, event): 10727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Insert a linefeed without entering anything (still autoindented) 10737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.reading: 10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.insert("insert", "\n") 10757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.see("insert") 10767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1077822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser self.newline_and_indent_event(event) 10787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def enter_callback(self, event): 10817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing and not self.reading: 10827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Let the default binding (insert '\n') take over 10837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If some text is selected, recall the selection 10847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # (but only if this before the I/O mark) 10857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 10867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sel = self.text.get("sel.first", "sel.last") 10877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if sel: 10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("sel.last", "<=", "iomark"): 1089a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.recall(sel, event) 10907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 10927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 10937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If we're strictly before the line containing iomark, recall 10947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # the current line, less a leading prompt, less leading or 10957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # trailing whitespace 10967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("insert", "<", "iomark linestart"): 10977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Check if there's a relevant stdin range -- if so, use it 10987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer prev = self.text.tag_prevrange("stdin", "insert") 10997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if prev and self.text.compare("insert", "<", prev[1]): 1100a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.recall(self.text.get(prev[0], prev[1]), event) 11017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer next = self.text.tag_nextrange("stdin", "insert") 11037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if next and self.text.compare("insert lineend", ">=", next[0]): 1104a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.recall(self.text.get(next[0], next[1]), event) 11057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11064ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser # No stdin mark -- just get the current line, less any prompt 1107b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser indices = self.text.tag_nextrange("console", "insert linestart") 1108b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser if indices and \ 1109b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser self.text.compare(indices[0], "<=", "insert linestart"): 1110b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser self.recall(self.text.get(indices[1], "insert lineend"), event) 1111b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser else: 1112b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser self.recall(self.text.get("insert linestart", "insert lineend"), event) 11137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 1114822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser # If we're between the beginning of the line and the iomark, i.e. 11154ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser # in the prompt area, move to the end of the prompt 1116822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser if self.text.compare("insert", "<", "iomark"): 11174ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser self.text.mark_set("insert", "iomark") 11187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If we're in the current input and there's only whitespace 11197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # beyond the cursor, erase that whitespace first 11207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = self.text.get("insert", "end-1c") 1121837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser if s and not s.strip(): 11227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.delete("insert", "end-1c") 11237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If we're in the current input before its last line, 11247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # insert a newline right at the insert point 11257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("insert", "<", "end-1c linestart"): 1126822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser self.newline_and_indent_event(event) 11277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # We're in the last line; append a newline and submit it 11297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "end-1c") 11307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.reading: 11317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.insert("insert", "\n") 11327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.see("insert") 11337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1134822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser self.newline_and_indent_event(event) 11357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_add("stdin", "iomark", "end-1c") 11367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.update_idletasks() 11377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.reading: 11387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.quit() # Break out of recursive mainloop() in raw_input() 11397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 11407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.runit() 11417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1143a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser def recall(self, s, event): 1144cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser # remove leading and trailing empty or whitespace lines 1145cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser s = re.sub(r'^\s*\n', '' , s) 1146cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser s = re.sub(r'\n\s*$', '', s) 1147cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser lines = s.split('\n') 1148a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.undo_block_start() 1149a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser try: 1150a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.tag_remove("sel", "1.0", "end") 1151a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.mark_set("insert", "end-1c") 1152cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser prefix = self.text.get("insert linestart", "insert") 1153cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser if prefix.rstrip().endswith(':'): 11548fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser self.newline_and_indent_event(event) 1155cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser prefix = self.text.get("insert linestart", "insert") 1156cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser self.text.insert("insert", lines[0].strip()) 11578fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser if len(lines) > 1: 1158cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0) 1159cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser new_base_indent = re.search(r'^([ \t]*)', prefix).group(0) 11608fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser for line in lines[1:]: 1161cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser if line.startswith(orig_base_indent): 1162cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser # replace orig base indentation with new indentation 1163cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser line = new_base_indent + line[len(orig_base_indent):] 1164cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser self.text.insert('insert', '\n'+line.rstrip()) 1165a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser finally: 1166a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.see("insert") 1167a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.undo_block_stop() 11687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 11697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def runit(self): 11707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = self.text.get("iomark", "end-1c") 11717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Strip off last newline and surrounding whitespace. 11727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # (To allow you to hit return twice to end a statement.) 11737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = len(line) 11747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer while i > 0 and line[i-1] in " \t": 11757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = i-1 11767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if i > 0 and line[i-1] == "\n": 11777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = i-1 11787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer while i > 0 and line[i-1] in " \t": 11797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = i-1 11807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = line[:i] 11817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer more = self.interp.runsource(line) 11827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 11837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_stack_viewer(self, event=None): 11845d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.interp.rpcclt: 11855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return self.interp.remote_stack_viewer() 11867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 11877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.last_traceback 11887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 11897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror("No stack trace", 11907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "There is no stack trace yet.\n" 11917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "(sys.last_traceback is not defined)", 11927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.text) 11937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 1194d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib.StackViewer import StackBrowser 11957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sv = StackBrowser(self.root, self.flist) 11967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 11971061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser def view_restart_mark(self, event=None): 11981061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser self.text.see("iomark") 11991061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser self.text.see("restart") 12001061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser 12011061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser def restart_shell(self, event=None): 120267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.interp.restart_subprocess() 12031061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser 12047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def showprompt(self): 12057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 12067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 12077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = str(sys.ps1) 12087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 12097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = "" 12107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.console.write(s) 12117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "end-1c") 12125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.set_line_and_column() 1213dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser self.io.reset_undo() 12147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def resetoutput(self): 12167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer source = self.text.get("iomark", "end-1c") 12177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.history: 12187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.history.history_store(source) 12197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.get("end-2c") != "\n": 12207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.insert("end-1c", "\n") 12217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("iomark", "end-1c") 12225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.set_line_and_column() 12237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stdout.softspace = 0 12247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def write(self, s, tags=()): 1226003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser try: 1227003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.text.mark_gravity("iomark", "right") 1228003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser OutputWindow.write(self, s, tags, "iomark") 1229003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.text.mark_gravity("iomark", "left") 1230003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser except: 1231003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser pass 12327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.canceled: 12337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 12347f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if not use_subprocess: 12357f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser raise KeyboardInterrupt 12367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1237dcba6622f52efafa28104a07db9d5ba2b1a8d628Kurt B. Kaiserclass PseudoFile(object): 12387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1239bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis def __init__(self, shell, tags, encoding=None): 12407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.shell = shell 12417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tags = tags 12425d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.softspace = 0 1243bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis self.encoding = encoding 12447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def write(self, s): 12467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.shell.write(s, self.tags) 12477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1248d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna def writelines(self, lines): 1249d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna for line in lines: 1250d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna self.write(line) 12517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def flush(self): 12537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 12547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def isatty(self): 1256837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return True 12577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1258969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser 12597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\ 12607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 126111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle [-deins] [-t title] [file]* 126211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser idle [-dns] [-t title] (-c cmd | -r file) [arg]* 126311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser idle [-dns] [-t title] - [arg]* 12646655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 1265f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -h print this help message and exit 12668f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser -n run IDLE without a subprocess (see Help/IDLE Help for details) 1267f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1268f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration: 1269f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1270f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -e open an edit window 1271f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -i open a shell window 1272f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1273f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell: 1274f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1275f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -c cmd run the command in a shell, or 1276f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -r file run script from file 1277f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1278f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -d enable the debugger 1279f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else 1280f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -t title set title of shell window 1281f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1282f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used. 1283f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1284f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:]. 1285f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1286f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples: 12877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1288f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle 1289f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open an edit window or shell depending on IDLE's configuration. 129096d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser 1291f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py 1292f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Edit the files, also open a shell if configured to start with shell. 1293f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1294f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py 1295f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell 1296f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser window with the title "Baz". 1297f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1298f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo" 1299f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open a shell window and run the command, passing "-c" in sys.argv[0] 1300f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser and "foo" in sys.argv[1]. 1301f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1302f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World" 1303f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open a shell window, run a startup script, enable the debugger, and 1304f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in 1305f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv[1]. 1306f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1307f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar" 1308f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open a shell window, run the script piped in, passing '' in sys.argv[0] 1309f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser and "foobar" in sys.argv[1]. 13107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer""" 13117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1312969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main(): 1313f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser global flist, root, use_subprocess 1314f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 13158f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser use_subprocess = True 1316013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser enable_shell = True 1317f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = False 1318f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser debug = False 1319969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser cmd = None 1320969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser script = None 1321f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser startup = False 1322969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser try: 13238f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") 1324969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser except getopt.error, msg: 1325969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.stderr.write("Error: %s\n" % str(msg)) 1326969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.stderr.write(usage_msg) 1327969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.exit(2) 1328969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser for o, a in opts: 1329969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-c': 1330969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser cmd = a 1331f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1332969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-d': 1333f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser debug = True 1334f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1335969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-e': 1336f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = True 1337013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser enable_shell = False 1338f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if o == '-h': 1339f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.stdout.write(usage_msg) 1340f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.exit() 1341f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if o == '-i': 1342f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 13438f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser if o == '-n': 13448f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser use_subprocess = False 1345969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-r': 1346969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser script = a 1347f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if os.path.isfile(script): 1348f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser pass 1349f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser else: 1350f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser print "No script file: ", script 1351f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.exit() 1352f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1353969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-s': 1354f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser startup = True 1355f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1356969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-t': 1357969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser PyShell.shell_title = a 1358f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1359f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if args and args[0] == '-': 1360f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser cmd = sys.stdin.read() 1361f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1362f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # process sys.argv and sys.path: 1363969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser for i in range(len(sys.path)): 1364969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.path[i] = os.path.abspath(sys.path[i]) 1365f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if args and args[0] == '-': 1366f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv = [''] + args[1:] 1367f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif cmd: 1368f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv = ['-c'] + args 1369f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif script: 1370f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv = [script] + args 1371f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif args: 1372f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = True 1373f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser pathx = [] 1374969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser for filename in args: 1375969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser pathx.append(os.path.dirname(filename)) 1376f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser for dir in pathx: 1377f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser dir = os.path.abspath(dir) 1378d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna if dir not in sys.path: 1379f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.path.insert(0, dir) 1380ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser else: 1381ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser dir = os.getcwd() 1382ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser if not dir in sys.path: 1383ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser sys.path.insert(0, dir) 1384f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # check the IDLE settings configuration (but command line overrides) 1385f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser edit_start = idleConf.GetOption('main', 'General', 13866655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 'editor-on-startup', type='bool') 1387f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = enable_edit or edit_start 1388f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # start editor and/or shell windows: 1389969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root = Tk(className="Idle") 139019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1391969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser fixwordbreaks(root) 1392969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root.withdraw() 1393969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser flist = PyShellFileList(root) 139419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren macosxSupport.setupApp(root, flist) 139519302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1396f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if enable_edit: 1397f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if not (cmd or script): 1398f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser for filename in args: 1399f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser flist.open(filename) 1400f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if not args: 1401f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser flist.new() 1402af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if enable_shell: 140319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren shell = flist.open_shell() 140419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren if not shell: 1405af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return # couldn't open shell 140619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 140719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren if macosxSupport.runningAsOSXApp() and flist.dict: 140819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren # On OSX: when the user has double-clicked on a file that causes 14094f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters # IDLE to be launched the shell window will open just in front of 14104f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters # the file she wants to see. Lower the interpreter window when 141119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren # there are open files. 141219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren shell.top.lower() 141319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1414f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell = flist.pyshell 1415f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # handle remaining options: 1416f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if debug: 1417f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.open_debugger() 1418969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if startup: 1419969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser filename = os.environ.get("IDLESTARTUP") or \ 1420969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser os.environ.get("PYTHONSTARTUP") 1421969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if filename and os.path.isfile(filename): 1422f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.execfile(filename) 1423af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if shell and cmd or script: 1424f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.runcommand("""if 1: 1425f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser import sys as _sys 142670a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald _sys.argv = %r 1427f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser del _sys 142870a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald \n""" % (sys.argv,)) 1429f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if cmd: 1430f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.execsource(cmd) 1431f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif script: 143211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser shell.interp.prepend_syspath(script) 1433f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.execfile(script) 143419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1435969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root.mainloop() 1436969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root.destroy() 1437969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser 14387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__": 14399e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser sys.modules['PyShell'] = sys.modules['__main__'] 14407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer main() 1441