PyShell.py revision 53dc4f0148f08d0da5c394089b7061cd77269fc0
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 14e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwisimport io 157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport linecache 177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom code import InteractiveInterpreter 18d676a3a221b99e1b352e18be0939158dfc37ef82Terry Jan Reedyfrom platform import python_version 197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 202303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaisertry: 216634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl from Tkinter import * 222303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiserexcept ImportError: 236634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl print>>sys.__stderr__, "** IDLE can't import Tkinter. " \ 242303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser "Your Python may not be configured for Tk. **" 252303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser sys.exit(1) 266634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandlimport tkMessageBox 277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 28d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.EditorWindow import EditorWindow, fixwordbreaks 29d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.FileList import FileList 30d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.ColorDelegator import ColorDelegator 31d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.UndoDelegator import UndoDelegator 32d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.OutputWindow import OutputWindow 33d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.configHandler import idleConf 34d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import idlever 35d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import rpc 36d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import Debugger 37d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import RemoteDebugger 38d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import macosxSupport 395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 40b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_" 41013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserHOST = '127.0.0.1' # python execution server on localhost loopback 42013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserPORT = 0 # someday pass in host, port for remote debug capability 43b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser 44a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry: 45a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser from signal import SIGTERM 46a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError: 47a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser SIGTERM = 15 48a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser 4949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# Override warnings module to write to warning_stream. Initialize to send IDLE 5049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# internal warnings to the console. ScriptBinding.check_syntax() will 5149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# temporarily redirect the stream to the shell window to display warnings when 5249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# checking user's code. 5349a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiserglobal warning_stream 5449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiserwarning_stream = sys.__stderr__ 555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teytry: 565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey import warnings 575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyexcept ImportError: 585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey pass 595d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyelse: 60b76444b2fa39a99984ffa4bcfa9806fbb091594aBenjamin Peterson def idle_showwarning(message, category, filename, lineno, 61b76444b2fa39a99984ffa4bcfa9806fbb091594aBenjamin Peterson file=None, line=None): 62f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo if file is None: 63f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo file = warning_stream 6449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser try: 65f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo file.write(warnings.formatwarning(message, category, filename, 6613502b19c64b2cd37b0b2b66dfcc26d0f028cd84Senthil Kumaran lineno, line=line)) 6749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser except IOError: 6849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser pass ## file (probably __stderr__) is invalid, warning dropped. 695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey warnings.showwarning = idle_showwarning 70f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo def idle_formatwarning(message, category, filename, lineno, line=None): 7149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser """Format warnings the IDLE way""" 7249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s = "\nWarning (from warnings module):\n" 7349a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s += ' File \"%s\", line %s\n' % (filename, lineno) 74f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo if line is None: 75f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo line = linecache.getline(filename, lineno) 76f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo line = line.strip() 7749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser if line: 7849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s += " %s\n" % line 7949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser s += "%s: %s\n>>> " % (category.__name__, message) 8049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser return s 8149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser warnings.formatwarning = idle_formatwarning 825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 83f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiserdef extended_linecache_checkcache(filename=None, 84f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser orig_checkcache=linecache.checkcache): 8545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser """Extend linecache.checkcache to preserve the <pyshell#...> entries 8645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 87f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser Rather than repeating the linecache code, patch it to save the 88f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser <pyshell#...> entries, call the original linecache.checkcache() 89f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo (skipping them), and then restore the saved entries. 90f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser 91f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser orig_checkcache is bound at definition time to the original 92f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser method, allowing it to be patched. 9345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser """ 947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer cache = linecache.cache 957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer save = {} 96f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo for key in list(cache): 97f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo if key[:1] + key[-1:] == '<>': 98f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo save[key] = cache.pop(key) 99f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo orig_checkcache(filename) 1007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer cache.update(save) 1016655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 102818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache(): 103818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache 1047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 1067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow): 107183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser "Regular text edit window in IDLE, supports breakpoints" 10845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 1097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, *args): 11045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints = [] 111931237e2e66975c54e2ac6c5e503ee2992a22bcfRaymond Hettinger EditorWindow.__init__(self, *args) 1127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here) 11345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here) 1147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind("<<open-python-shell>>", self.flist.open_shell) 1157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 116bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(), 117bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser 'breakpoints.lst') 118a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey # whenever a file is changed, restore breakpoints 119bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser def filename_changed_hook(old_hook=self.io.filename_change_hook, 120bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self=self): 121a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.restore_file_breaks() 122a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey old_hook() 123a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.io.set_filename_change_hook(filename_changed_hook) 124d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy if self.io.filename: 125d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy self.restore_file_breaks() 126a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 1275018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov rmenu_specs = [ 1285018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov ("Cut", "<<cut>>", "rmenu_check_cut"), 1295018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov ("Copy", "<<copy>>", "rmenu_check_copy"), 1305018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov ("Paste", "<<paste>>", "rmenu_check_paste"), 1315018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov ("Set Breakpoint", "<<set-breakpoint-here>>", None), 1325018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov ("Clear Breakpoint", "<<clear-breakpoint-here>>", None) 1335018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov ] 1347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 135a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def set_breakpoint(self, lineno): 13645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text = self.text 13745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser filename = self.io.filename 138a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1)) 13945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 14045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser i = self.breakpoints.index(lineno) 141a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey except ValueError: # only add if missing, i.e. do once 14245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints.append(lineno) 14345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: # update the subprocess debugger 14445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.flist.pyshell.interp.debugger 14545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.set_breakpoint_here(filename, lineno) 14645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: # but debugger may not be active right now.... 14745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 1487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 149a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def set_breakpoint_here(self, event=None): 150a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text = self.text 151a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey filename = self.io.filename 152a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey if not filename: 153a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text.bell() 154a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey return 155a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey lineno = int(float(text.index("insert"))) 156a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.set_breakpoint(lineno) 157a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 158669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser def clear_breakpoint_here(self, event=None): 15945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text = self.text 16045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser filename = self.io.filename 16145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if not filename: 16245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.bell() 163669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser return 16445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser lineno = int(float(text.index("insert"))) 16545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 16645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints.remove(lineno) 16745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: 16845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 16945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.tag_remove("BREAK", "insert linestart",\ 17045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser "insert lineend +1char") 17145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 17245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.flist.pyshell.interp.debugger 17345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.clear_breakpoint_here(filename, lineno) 17445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: 17545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 17645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 17745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def clear_file_breaks(self): 17845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if self.breakpoints: 17945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text = self.text 18045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser filename = self.io.filename 18145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if not filename: 18245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.bell() 18345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser return 18445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.breakpoints = [] 18545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser text.tag_remove("BREAK", "1.0", END) 18645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser try: 18745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.flist.pyshell.interp.debugger 18845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.clear_file_breaks(filename) 18945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser except: 19045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser pass 19145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 192a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def store_file_breaks(self): 193bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser "Save breakpoints when file is saved" 194bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # XXX 13 Dec 2002 KBK Currently the file must be saved before it can 195bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # be run. The breaks are saved at that time. If we introduce 196bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # a temporary file save feature the save breaks functionality 197bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # needs to be re-verified, since the breaks at the time the 198bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # temp file is created may differ from the breaks at the last 1997f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # permanent save of the file. Currently, a break introduced 2007f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # after a save will be effective, but not persistent. 2017f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # This is necessary to keep the saved breaks synched with the 2027f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser # saved file. 203bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # 204bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # Breakpoints are set as tagged ranges in the text. Certain 205bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # kinds of edits cause these ranges to be deleted: Inserting 206bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # or deleting a line just before a breakpoint, and certain 207bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # deletions prior to a breakpoint. These issues need to be 208bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # investigated and understood. It's not clear if they are 209bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # Tk issues or IDLE issues, or whether they can actually 210bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # be fixed. Since a modified file has to be saved before it is 211bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # run, and since self.breakpoints (from which the subprocess 212bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # debugger is loaded) is updated during the save, the visible 213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # breaks stay synched with the subprocess even if one of these 214bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser # unexpected breakpoint deletions occurs. 215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser breaks = self.breakpoints 216bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser filename = self.io.filename 217a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey try: 21840ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily with open(self.breakpointPath,"r") as old_file: 21940ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily lines = old_file.readlines() 220a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey except IOError: 221bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = [] 22240ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily try: 22340ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily with open(self.breakpointPath,"w") as new_file: 22440ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily for line in lines: 22540ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily if not line.startswith(filename + '='): 22640ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily new_file.write(line) 22740ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily self.update_breakpoints() 22840ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily breaks = self.breakpoints 22940ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily if breaks: 23040ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily new_file.write(filename + '=' + str(breaks) + '\n') 23140ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily except IOError as err: 23240ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily if not getattr(self.root, "breakpoint_error_displayed", False): 23340ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily self.root.breakpoint_error_displayed = True 23440ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily tkMessageBox.showerror(title='IDLE Error', 23540ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily message='Unable to update breakpoint list:\n%s' 23640ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily % str(err), 23740ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily parent=self.text) 238a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 239a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey def restore_file_breaks(self): 240a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey self.text.update() # this enables setting "BREAK" tags to be visible 241d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy if self.io is None: 242d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy # can happen if IDLE closes due to the .update() call 243d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy return 244bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser filename = self.io.filename 245bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser if filename is None: 246bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser return 24769371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey if os.path.isfile(self.breakpointPath): 248bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = open(self.breakpointPath,"r").readlines() 24969371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey for line in lines: 250bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser if line.startswith(filename + '='): 2516655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser breakpoint_linenumbers = eval(line[len(filename)+1:]) 25269371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey for breakpoint_linenumber in breakpoint_linenumbers: 25369371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey self.set_breakpoint(breakpoint_linenumber) 254a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey 255bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser def update_breakpoints(self): 256bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser "Retrieves all the breakpoints in the current window" 257a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey text = self.text 258bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser ranges = text.tag_ranges("BREAK") 259bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser linenumber_list = self.ranges_to_linenumbers(ranges) 260bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser self.breakpoints = linenumber_list 261bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser 262bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser def ranges_to_linenumbers(self, ranges): 263bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines = [] 264bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser for index in range(0, len(ranges), 2): 2658a15c37df7415189f6e9291df074fba68b68df43Andrew Svetlov lineno = int(float(ranges[index].string)) 2668a15c37df7415189f6e9291df074fba68b68df43Andrew Svetlov end = int(float(ranges[index+1].string)) 267bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser while lineno < end: 268bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lines.append(lineno) 269bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser lineno += 1 270bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser return lines 271bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser 27211220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently 273bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# def saved_change_hook(self): 274bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# "Extend base method - clear breaks if module is modified" 275bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# if not self.get_saved(): 276bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# self.clear_file_breaks() 277bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser# EditorWindow.saved_change_hook(self) 27845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 27945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def _close(self): 28045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser "Extend base method - clear breaks when module is closed" 28145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.clear_file_breaks() 28245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser EditorWindow._close(self) 2836655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 2847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList): 286183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser "Extend base class: IDLE supports a shell and breakpoints" 2877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 288183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser # override FileList's class variable, instances return PyShellEditorWindow 289183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser # instead of EditorWindow when new edit windows are created. 2907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer EditorWindow = PyShellEditorWindow 2917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pyshell = None 2937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_shell(self, event=None): 2957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.pyshell: 296183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser self.pyshell.top.wakeup() 2977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 2987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.pyshell = PyShell(self) 299af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if self.pyshell: 300af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if not self.pyshell.begin(): 301af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 3027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.pyshell 3037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator): 30683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class: colorizer for the shell window itself" 3076655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 308b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava def __init__(self): 309b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava ColorDelegator.__init__(self) 310b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava self.LoadTagDefs() 3117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def recolorize_main(self): 3137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tag_remove("TODO", "1.0", "iomark") 3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tag_add("SYNC", "1.0", "iomark") 3157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ColorDelegator.recolorize_main(self) 3166655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 317b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava def LoadTagDefs(self): 318b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava ColorDelegator.LoadTagDefs(self) 319b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava theme = idleConf.GetOption('main','Theme','name') 320b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava self.tagdefs.update({ 321b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "stdin": {'background':None,'foreground':None}, 322b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "stdout": idleConf.GetHighlight(theme, "stdout"), 323b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "stderr": idleConf.GetHighlight(theme, "stderr"), 324b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava "console": idleConf.GetHighlight(theme, "console"), 325b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava }) 3267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3275e247b705e3bdd77967bca76601b791003389adaNed Deily def removecolors(self): 3285e247b705e3bdd77967bca76601b791003389adaNed Deily # Don't remove shell color tags before "iomark" 3295e247b705e3bdd77967bca76601b791003389adaNed Deily for tag in self.tagdefs: 3305e247b705e3bdd77967bca76601b791003389adaNed Deily self.tag_remove(tag, "iomark", "end") 3315e247b705e3bdd77967bca76601b791003389adaNed Deily 3327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator): 33383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class: forbid insert/delete before the I/O mark" 3347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def insert(self, index, chars, tags=None): 3367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 3377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.delegate.compare(index, "<", "iomark"): 3387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.delegate.bell() 3397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 3407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except TclError: 3417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 3427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer UndoDelegator.insert(self, index, chars, tags) 3437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def delete(self, index1, index2=None): 3457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 3467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.delegate.compare(index1, "<", "iomark"): 3477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.delegate.bell() 3487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 3497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except TclError: 3507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 3517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer UndoDelegator.delete(self, index1, index2) 3527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 35367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser 35467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient): 35567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser 35667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser def handle_EOF(self): 35767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser "Override the base class - just re-raise EOFError" 35867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser raise EOFError 35967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser 3608d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser 3617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter): 3627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, tkconsole): 3647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole = tkconsole 3657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer locals = sys.modules['__main__'].__dict__ 3667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer InteractiveInterpreter.__init__(self, locals=locals) 36794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = None 3686f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser self.restarting = False 369013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.subprocess_arglist = None 370013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.port = PORT 37186d669bdb849ab5cf99623494c706a5ab416e84eNed Deily self.original_compiler_flags = self.compile.compiler.flags 3727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3735d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey rpcclt = None 3745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey rpcpid = None 3755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 3766655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser def spawn_subprocess(self): 377c8a730bf72b1c95651a8a39766bf56635956a2e0Florent Xicluna if self.subprocess_arglist is None: 378013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.subprocess_arglist = self.build_subprocess_arglist() 37962df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser args = self.subprocess_arglist 380b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) 38163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser 382f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds def build_subprocess_arglist(self): 383013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser assert (self.port!=0), ( 384013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "Socket should have been assigned a port number.") 3852398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds w = ['-W' + s for s in sys.warnoptions] 386d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl if 1/2 > 0: # account for new division 387d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl w.append('-Qnew') 3882398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds # Maybe IDLE is installed and is being accessed via sys.path, 3892398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds # or maybe it's not installed and the idle.py script is being 3902398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds # run from the IDLE source directory. 39162df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc', 39262df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser default=False, type='bool') 3932398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds if __name__ == 'idlelib.PyShell': 39470a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) 395f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds else: 39670a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald command = "__import__('run').main(%r)" % (del_exitf,) 397b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser if sys.platform[:3] == 'win' and ' ' in sys.executable: 398b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser # handle embedded space in path by quoting the argument 399b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser decorated_exec = '"%s"' % sys.executable 400b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser else: 401b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser decorated_exec = sys.executable 402b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser return [decorated_exec] + w + ["-c", command, str(self.port)] 403f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds 40463857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser def start_subprocess(self): 405013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser addr = (HOST, self.port) 406013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # GUI makes several attempts to acquire socket, listens for connection 4075db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser for i in range(3): 4085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey time.sleep(i) 4095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey try: 41067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.rpcclt = MyRPCClient(addr) 4115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey break 4125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey except socket.error, err: 413af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser pass 4145d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey else: 415af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.display_port_binding_error() 416af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 417013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # if PORT was 0, system will assign an 'ephemeral' port. Find it out: 418013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.port = self.rpcclt.listening_sock.getsockname()[1] 419013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # if PORT was not 0, probably working with a remote execution server 420013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser if PORT != 0: 421013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # To allow reconnection within the 2MSL wait (cf. Stevens TCP 422013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic 423013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # on Windows since the implementation allows two active sockets on 424013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser # the same address! 425013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, 426013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser socket.SO_REUSEADDR, 1) 427013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser self.spawn_subprocess() 428013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser #time.sleep(20) # test to simulate GUI not accepting connection 429b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser # Accept the connection from the Python execution server 430af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.listening_sock.settimeout(10) 431af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser try: 432af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.accept() 433af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser except socket.timeout, err: 434af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.display_no_subprocess_error() 435af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 4369abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self.rpcclt.register("console", self.tkconsole) 4379abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self.rpcclt.register("stdin", self.tkconsole.stdin) 438969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser self.rpcclt.register("stdout", self.tkconsole.stdout) 439969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser self.rpcclt.register("stderr", self.tkconsole.stderr) 4405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.rpcclt.register("flist", self.tkconsole.flist) 4418cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser self.rpcclt.register("linecache", linecache) 4429f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser self.rpcclt.register("interp", self) 443b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy self.transfer_path(with_cwd=True) 4445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.poll_subprocess() 445af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return self.rpcclt 4465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 447b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy def restart_subprocess(self, with_cwd=False): 4486f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser if self.restarting: 449af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return self.rpcclt 4506f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser self.restarting = True 45163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser # close only the subprocess debugger 45245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug = self.getdebugger() 45345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if debug: 454003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser try: 4559ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser # Only close subprocess debugger, don't unregister gui_adap! 456003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser RemoteDebugger.close_subprocess_debugger(self.rpcclt) 457003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser except: 458003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser pass 459003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser # Kill subprocess, spawn a new one, accept connection. 460a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt.close() 461a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.unix_terminate() 4627f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser console = self.tkconsole 4636f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser was_executing = console.executing 4647f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser console.executing = False 46563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser self.spawn_subprocess() 466af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser try: 467af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.accept() 468af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser except socket.timeout, err: 469af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.display_no_subprocess_error() 470af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return None 471b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy self.transfer_path(with_cwd=with_cwd) 472ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy console.stop_readline() 4731061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser # annotate restart in shell window and mark it 4744cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser console.text.delete("iomark", "end-1c") 4756f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser if was_executing: 4766f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser console.write('\n') 4776f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser console.showprompt() 4781061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser halfbar = ((int(console.width) - 16) // 2) * '=' 4791061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser console.write(halfbar + ' RESTART ' + halfbar) 4801061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser console.text.mark_set("restart", "end-1c") 4811061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser console.text.mark_gravity("restart", "left") 4827f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser console.showprompt() 483003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser # restart subprocess debugger 48445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser if debug: 4859ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser # Restarted debugger connects to current instance of debug GUI 48663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt) 48745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser # reload remote debugger breakpoints for all PyShellEditWindows 48845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debug.load_breakpoints() 48986d669bdb849ab5cf99623494c706a5ab416e84eNed Deily self.compile.compiler.flags = self.original_compiler_flags 4906f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser self.restarting = False 491af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return self.rpcclt 49245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 493003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser def __request_interrupt(self): 494a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt.remotecall("exec", "interrupt_the_server", (), {}) 495003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser 496003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser def interrupt_subprocess(self): 497a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser threading.Thread(target=self.__request_interrupt).start() 498003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser 499a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser def kill_subprocess(self): 500af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser try: 501af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.rpcclt.close() 502af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser except AttributeError: # no socket 503af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser pass 504a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.unix_terminate() 505a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.tkconsole.executing = False 506a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt = None 50711c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser 508a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser def unix_terminate(self): 509a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser "UNIX: make sure subprocess is terminated and collect status" 510a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser if hasattr(os, 'kill'): 511a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser try: 512a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser os.kill(self.rpcpid, SIGTERM) 513a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser except OSError: 514a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser # process already terminated: 515a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser return 516a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser else: 517a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser try: 518a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser os.waitpid(self.rpcpid, 0) 519a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser except OSError: 520a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser return 52111c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser 522b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy def transfer_path(self, with_cwd=False): 523b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy if with_cwd: # Issue 13506 524b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy path = [''] # include Current Working Directory 525b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy path.extend(sys.path) 526b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy else: 527b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy path = sys.path 5281d4ae48f48b2da82a89769a714644eb55a541888Terry Jan Reedy 529f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser self.runcommand("""if 1: 530f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser import sys as _sys 53170a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald _sys.path = %r 532f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser del _sys 533b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy \n""" % (path,)) 534f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 5355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey active_seq = None 5365d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 5375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey def poll_subprocess(self): 5385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey clt = self.rpcclt 5395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if clt is None: 5405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 541003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser try: 542a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser response = clt.pollresponse(self.active_seq, wait=0.05) 543a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser except (EOFError, IOError, KeyboardInterrupt): 544a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser # lost connection or subprocess terminated itself, restart 545a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser # [the KBI is from rpc.SocketIO.handle_EOF()] 54667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser if self.tkconsole.closing: 54767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser return 548003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser response = None 549003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.restart_subprocess() 5505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if response: 5515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.tkconsole.resetoutput() 5525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.active_seq = None 5535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey how, what = response 554bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser console = self.tkconsole.console 5555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if how == "OK": 5565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if what is not None: 55770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald print >>console, repr(what) 5585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey elif how == "EXCEPTION": 5595d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): 5605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.remote_stack_viewer() 5615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey elif how == "ERROR": 5620930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n" 5630930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser print >>sys.__stderr__, errmsg, what 564bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser print >>console, errmsg, what 565bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser # we received a response to the currently active seq number: 566d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser try: 567d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser self.tkconsole.endexecuting() 568d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser except AttributeError: # shell may have closed 569d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser pass 57088957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser # Reschedule myself 57188957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser if not self.tkconsole.closing: 57288957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser self.tkconsole.text.after(self.tkconsole.pollinterval, 57388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser self.poll_subprocess) 5745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 57545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser debugger = None 57645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 57745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def setdebugger(self, debugger): 57845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser self.debugger = debugger 57945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 58045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser def getdebugger(self): 58145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser return self.debugger 58245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser 5839f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser def open_remote_stack_viewer(self): 5849f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser """Initiate the remote stack viewer from a separate thread. 5859f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser 5869f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser This method is called from the subprocess, and by returning from this 5879f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser method we allow the subprocess to unblock. After a bit the shell 5889f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser requests the subprocess to open the remote stack viewer which returns a 589c569cfebcebd3d3c8cf77e6c8971a19c78ff7261Ezio Melotti static object looking at the last exception. It is queried through 5909f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser the RPC mechanism. 5919f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser 5929f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser """ 5939f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser self.tkconsole.text.after(300, self.remote_stack_viewer) 5949f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser return 5959f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser 5965d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey def remote_stack_viewer(self): 597d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import RemoteObjectBrowser 598a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {}) 5995d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if oid is None: 6005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.tkconsole.root.bell() 6015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 6025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) 603d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib.TreeWidget import ScrolledCanvas, TreeNode 6045d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey top = Toplevel(self.tkconsole.root) 60573360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser theme = idleConf.GetOption('main','Theme','name') 60673360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser background = idleConf.GetHighlight(theme, 'normal')['background'] 60773360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser sc = ScrolledCanvas(top, bg=background, highlightthickness=0) 6085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sc.frame.pack(expand=1, fill="both") 6095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey node = TreeNode(sc.canvas, None, item) 6105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey node.expand() 6115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey # XXX Should GC the remote tree when closing the window 6125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 6137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer gid = 0 6147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def execsource(self, source): 61683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Like runsource() but assumes complete exec source" 6177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.stuffsource(source) 6187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.execfile(filename, source) 6197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def execfile(self, filename, source=None): 62183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Execute an existing file" 6227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if source is None: 6237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer source = open(filename, "r").read() 6247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 6257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer code = compile(source, filename, "exec") 6267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except (OverflowError, SyntaxError): 6277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole.resetoutput() 6287f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser tkerr = self.tkconsole.stderr 6297f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser print>>tkerr, '*** Error in script or command!\n' 6307f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser print>>tkerr, 'Traceback (most recent call last):' 6317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer InteractiveInterpreter.showsyntaxerror(self, filename) 6326e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.tkconsole.showprompt() 6337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 6347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.runcode(code) 6357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def runsource(self, source): 63783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class method: Stuff the source in the line cache first" 6387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.stuffsource(source) 6397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.more = 0 64094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = warnings.filters[:] 64194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser warnings.filterwarnings(action="error", category=SyntaxWarning) 642837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser if isinstance(source, types.UnicodeType): 643d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import IOBinding 644837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser try: 645837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser source = source.encode(IOBinding.encoding) 646837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser except UnicodeError: 647837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser self.tkconsole.resetoutput() 648cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser self.write("Unsupported characters in input\n") 649837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return 65094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser try: 651935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser # InteractiveInterpreter.runsource() calls its runcode() method, 652935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser # which is overridden (see below) 65394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser return InteractiveInterpreter.runsource(self, source, filename) 65494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser finally: 65594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser if self.save_warnings_filters is not None: 65694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser warnings.filters[:] = self.save_warnings_filters 65794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = None 6587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def stuffsource(self, source): 66083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Stuff source in the filename cache" 6617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = "<pyshell#%d>" % self.gid 6627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.gid = self.gid + 1 663837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser lines = source.split("\n") 6647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer linecache.cache[filename] = len(source)+1, 0, lines, filename 6657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return filename 6666655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 66711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser def prepend_syspath(self, filename): 66811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser "Prepend sys.path with file's directory if not already included" 66911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser self.runcommand("""if 1: 67070a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald _filename = %r 67111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser import sys as _sys 67211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser from os.path import dirname as _dirname 67311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser _dir = _dirname(_filename) 67411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser if not _dir in _sys.path: 67511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser _sys.path.insert(0, _dir) 67611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser del _filename, _sys, _dirname, _dir 67770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald \n""" % (filename,)) 67811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser 6797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def showsyntaxerror(self, filename=None): 68083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser """Extend base class method: Add Colorizing 68183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser 68283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser Color the offending position instead of printing it and pointing at it 68383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser with a caret. 68483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser 68583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser """ 6867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.tkconsole.text 6877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer stuff = self.unpackerror() 6886e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser if stuff: 6896e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser msg, lineno, offset, line = stuff 6906e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser if lineno == 1: 6916e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser pos = "iomark + %d chars" % (offset-1) 6926e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser else: 6936e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser pos = "iomark linestart + %d lines + %d chars" % \ 6946e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser (lineno-1, offset-1) 6956e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser text.tag_add("ERROR", pos) 6966e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser text.see(pos) 6976e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser char = text.get(pos) 6986e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser if char and char in IDENTCHARS: 6996e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser text.tag_add("ERROR", pos + " wordstart", pos) 7007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole.resetoutput() 7016e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.write("SyntaxError: %s\n" % str(msg)) 7027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 7036e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.tkconsole.resetoutput() 7046e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser InteractiveInterpreter.showsyntaxerror(self, filename) 7056e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser self.tkconsole.showprompt() 7067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def unpackerror(self): 7087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer type, value, tb = sys.exc_info() 7097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ok = type is SyntaxError 7107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if ok: 7117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 7127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer msg, (dummy_filename, lineno, offset, line) = value 713bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser if not offset: 714bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser offset = 0 7157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 7167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ok = 0 7177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if ok: 7187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return msg, lineno, offset, line 7197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 7207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return None 7217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def showtraceback(self): 72383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend base class method to reset output properly" 7247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tkconsole.resetoutput() 7257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.checklinecache() 7267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer InteractiveInterpreter.showtraceback(self) 7275d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"): 7285d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.tkconsole.open_stack_viewer() 7297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def checklinecache(self): 7317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer c = linecache.cache 7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for key in c.keys(): 7337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if key[:1] + key[-1:] != "<>": 7347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer del c[key] 7357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7365d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey def runcommand(self, code): 73783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Run the code without invoking the debugger" 7385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey # The code better not raise an exception! 7395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.executing: 740f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz self.display_executing_dialog() 7415d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 0 7425d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.rpcclt: 743a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser self.rpcclt.remotequeue("exec", "runcode", (code,), {}) 7445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey else: 7455d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey exec code in self.locals 7465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return 1 7475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 7487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def runcode(self, code): 74983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Override base class method" 7505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.tkconsole.executing: 751003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.interp.restart_subprocess() 7525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.checklinecache() 75394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser if self.save_warnings_filters is not None: 75494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser warnings.filters[:] = self.save_warnings_filters 75594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser self.save_warnings_filters = None 7567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer debugger = self.debugger 7577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 7587f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.tkconsole.beginexecuting() 759dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if not debugger and self.rpcclt is not None: 760dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.active_seq = self.rpcclt.asyncqueue("exec", "runcode", 761dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser (code,), {}) 762dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser elif debugger: 763dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser debugger.run(code, self.locals) 764dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 765dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser exec code in self.locals 766dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser except SystemExit: 767dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if not self.tkconsole.closing: 768dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if tkMessageBox.askyesno( 769dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser "Exit?", 770dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser "Do you want to exit altogether?", 771dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser default="yes", 772dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser master=self.tkconsole.text): 773f137e1df2c02f5782c5b0f18a2b3b649f255f63aKurt B. Kaiser raise 774dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 775dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.showtraceback() 776dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 777dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser raise 778dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser except: 779dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if use_subprocess: 780dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser print >>self.tkconsole.stderr, \ 781dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser "IDLE internal error in runcode()" 7827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showtraceback() 783dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.tkconsole.endexecuting() 784dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 785dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser if self.tkconsole.canceled: 786dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.tkconsole.canceled = False 787dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser print >>self.tkconsole.stderr, "KeyboardInterrupt" 788dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser else: 789dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser self.showtraceback() 7907f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser finally: 7917f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if not use_subprocess: 792d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser try: 793d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser self.tkconsole.endexecuting() 794d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser except AttributeError: # shell may have closed 795d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser pass 7967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def write(self, s): 79883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Override base class method" 7997f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.tkconsole.stderr.write(s) 8007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 801af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser def display_port_binding_error(self): 802af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser tkMessageBox.showerror( 803af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "Port Binding Error", 804013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "IDLE can't bind to a TCP/IP port, which is necessary to " 805013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "communicate with its Python execution server. This might be " 806013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "because no networking is installed on this computer. " 807013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "Run IDLE with the -n command line switch to start without a " 808013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "subprocess and refer to Help/IDLE Help 'Running without a " 809013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser "subprocess' for further details.", 810af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser master=self.tkconsole.text) 811af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 812af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser def display_no_subprocess_error(self): 813af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser tkMessageBox.showerror( 814af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "Subprocess Startup Error", 815af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "IDLE's subprocess didn't make connection. Either IDLE can't " 816af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "start a subprocess or personal firewall software is blocking " 817af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "the connection.", 818af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser master=self.tkconsole.text) 819af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 820af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser def display_executing_dialog(self): 821af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser tkMessageBox.showerror( 822af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "Already executing", 823af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "The Python Shell window is already executing a command; " 824af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser "please wait until it is finished.", 825af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser master=self.tkconsole.text) 826af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 827af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser 8287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow): 8297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 830d676a3a221b99e1b352e18be0939158dfc37ef82Terry Jan Reedy shell_title = "Python " + python_version() + " Shell" 8317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Override classes 8337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ColorDelegator = ModifiedColorDelegator 8347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer UndoDelegator = ModifiedUndoDelegator 8357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 836f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # Override menus 837dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser menu_specs = [ 838dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("file", "_File"), 839dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("edit", "_Edit"), 8404cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser ("debug", "_Debug"), 8411061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser ("options", "_Options"), 842dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("windows", "_Windows"), 843dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ("help", "_Help"), 844dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser ] 8457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 84619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren if macosxSupport.runningAsOSXApp(): 84719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren del menu_specs[-3] 84819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren menu_specs[-2] = ("windows", "_Window") 84919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 85019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 8517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # New classes 852d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib.IdleHistory import History 8537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, flist=None): 8558f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser if use_subprocess: 85667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser ms = self.menu_specs 85767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser if ms[2][0] != "shell": 8587ae354846fff616746eeba6d27ccd5c175591caeKurt B. Kaiser ms.insert(2, ("shell", "She_ll")) 8597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.interp = ModifiedInterpreter(self) 8607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if flist is None: 8617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root = Tk() 8627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer fixwordbreaks(root) 8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.withdraw() 8647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist = PyShellFileList(root) 8655afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer OutputWindow.__init__(self, flist, None, None) 8675afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8686af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser## self.config(usetabs=1, indentwidth=8, context_use_ps1=1) 8696af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser self.usetabs = True 8706af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser # indentwidth must be 8 when using tabs. See note in EditorWindow: 8716af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser self.indentwidth = 8 8726af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser self.context_use_ps1 = True 8735afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 8757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.configure(wrap="char") 8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<newline-and-indent>>", self.enter_callback) 8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<plain-newline-and-indent>>", self.linefeed_callback) 8787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<interrupt-execution>>", self.cancel_callback) 8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<end-of-file>>", self.eof_callback) 8807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<open-stack-viewer>>", self.open_stack_viewer) 88157bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser text.bind("<<toggle-debugger>>", self.toggle_debugger) 8827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer) 8838f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser if use_subprocess: 8848f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser text.bind("<<view-restart>>", self.view_restart_mark) 8858f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser text.bind("<<restart-shell>>", self.restart_shell) 8865afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.save_stdout = sys.stdout 8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.save_stderr = sys.stderr 8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.save_stdin = sys.stdin 890d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import IOBinding 8919abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding) 8929abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding) 8939abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding) 8949abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self.console = PseudoOutputFile(self, "console", IOBinding.encoding) 8955d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if not use_subprocess: 8965d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.stdout = self.stdout 8975d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.stderr = self.stderr 898e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis sys.stdin = self.stdin 8995afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.history = self.History(self.text) 9015afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser # 90288957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser self.pollinterval = 50 # millisec 9035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 9044d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser def get_standard_extension_names(self): 9054d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser return idleConf.GetExtensions(shell_only=True) 9064d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser 907003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser reading = False 908003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser executing = False 909003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser canceled = False 910003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser endoffile = False 911003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser closing = False 912ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy _stop_readline_flag = False 9137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 91449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser def set_warning_stream(self, stream): 915d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro global warning_stream 916d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro warning_stream = stream 91749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser 91849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser def get_warning_stream(self): 91949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser return warning_stream 92049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser 9217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def toggle_debugger(self, event=None): 9227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing: 9237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror("Don't debug now", 9247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "You can only toggle the debugger when idle", 9257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.text) 9267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.set_debugger_indicator() 9277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 9287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 9297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db = self.interp.getdebugger() 9307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if db: 9317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close_debugger() 9327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 9337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.open_debugger() 9347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_debugger_indicator(self): 9367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db = self.interp.getdebugger() 9377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.setvar("<<toggle-debugger>>", not not db) 9387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9391061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser def toggle_jit_stack_viewer(self, event=None): 9407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass # All we need is the variable 9417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close_debugger(self): 9437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db = self.interp.getdebugger() 9447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if db: 9457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.interp.setdebugger(None) 9467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer db.close() 947ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser if self.interp.rpcclt: 948ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser RemoteDebugger.close_remote_debugger(self.interp.rpcclt) 9497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 9507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.console.write("[DEBUG OFF]\n") 9517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.ps1 = ">>> " 9527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showprompt() 9537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.set_debugger_indicator() 9547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_debugger(self): 9565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.interp.rpcclt: 9577f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, 9587f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self) 9597f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser else: 9607f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser dbg_gui = Debugger.Debugger(self) 9617f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.interp.setdebugger(dbg_gui) 9627f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser dbg_gui.load_breakpoints() 9635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey sys.ps1 = "[DEBUG ON]\n>>> " 9645d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.showprompt() 9655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.set_debugger_indicator() 9665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey 9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def beginexecuting(self): 968ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser "Helper for ModifiedInterpreter" 9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.executing = 1 9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def endexecuting(self): 97383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Helper for ModifiedInterpreter" 9747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.executing = 0 9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 9765d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.showprompt() 9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close(self): 97983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend EditorWindow.close()" 9807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing: 981003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser response = tkMessageBox.askokcancel( 9827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "Kill?", 983003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser "The program is still running!\n Do you want to kill it?", 9847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer default="ok", 9857f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser parent=self.text) 9865b63acd31e0e40c1a9a9e9762905b0054ff37994Benjamin Peterson if response is False: 9877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "cancel" 988ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy self.stop_readline() 9895c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.canceled = True 99067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.closing = True 99167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser # Wait for poll_subprocess() rescheduling to stop 99267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.text.after(2 * self.pollinterval, self.close2) 99388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser 99488957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser def close2(self): 99588957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser return EditorWindow.close(self) 9967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def _close(self): 99883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Extend EditorWindow._close(), shut down debugger and execution server" 9997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close_debugger() 10007f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if use_subprocess: 10017f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.interp.kill_subprocess() 10027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Restore std streams 10037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stdout = self.save_stdout 10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stderr = self.save_stderr 10057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stdin = self.save_stdin 10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Break cycles 10077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.interp = None 10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.console = None 10097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist.pyshell = None 10107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.history = None 101183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser EditorWindow._close(self) 10127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def ispythonsource(self, filename): 101483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Override EditorWindow method: never remove the colorizer" 1015837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return True 10167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def short_title(self): 10187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.shell_title 10197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 102094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser COPYRIGHT = \ 10218f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser 'Type "copyright", "credits" or "license()" for more information.' 102294bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser 10237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def begin(self): 10247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 10257f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if use_subprocess: 10267f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser nosub = '' 1027af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser client = self.interp.start_subprocess() 1028af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if not client: 1029af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser self.close() 10307663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser return False 10317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser else: 10327f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser nosub = "==== No Subprocess ====" 1033bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger self.write("Python %s on %s\n%s\n%s" % 1034bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger (sys.version, sys.platform, self.COPYRIGHT, nosub)) 10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showprompt() 10366634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl import Tkinter 10376634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl Tkinter._default_root = None # 03Jan04 KBK What's this? 10387663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser return True 10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1040ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy def stop_readline(self): 1041ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy if not self.reading: # no nested mainloop to exit. 1042ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy return 1043ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy self._stop_readline_flag = True 1044ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy self.top.quit() 1045ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy 10467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def readline(self): 10477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer save = self.reading 10487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 10497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.reading = 1 10505c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.top.mainloop() # nested mainloop() 10517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer finally: 10527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.reading = save 1053ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy if self._stop_readline_flag: 1054ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy self._stop_readline_flag = False 1055ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy return "" 10567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = self.text.get("iomark", "end-1c") 10575c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if len(line) == 0: # may be EOF if we quit our mainloop with Ctrl-C 10585c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser line = "\n" 1059bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis if isinstance(line, unicode): 1060d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib import IOBinding 1061bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis try: 1062bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis line = line.encode(IOBinding.encoding) 1063bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis except UnicodeError: 1064bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis pass 10657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 10667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.canceled: 10677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 10685c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if not use_subprocess: 10695c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser raise KeyboardInterrupt 10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.endoffile: 10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.endoffile = 0 10725c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser line = "" 10737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return line 10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 10757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def isatty(self): 1076837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser return True 10777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1078003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser def cancel_callback(self, event=None): 10797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 10807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("sel.first", "!=", "sel.last"): 10817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Active selection -- always use default binding 10827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 10837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 10847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not (self.executing or self.reading): 10857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 10867f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser self.interp.write("KeyboardInterrupt\n") 10877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showprompt() 10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.endoffile = 0 1090003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.canceled = 1 10915c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if (self.executing and self.interp.rpcclt): 109267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser if self.interp.getdebugger(): 109367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.interp.restart_subprocess() 109467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser else: 109567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser self.interp.interrupt_subprocess() 10965c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser if self.reading: 10975c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser self.top.quit() # exit the nested mainloop() in readline() 10987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 10997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 11007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def eof_callback(self, event): 11017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing and not self.reading: 11027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Let the default binding (delete next char) take over 11037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not (self.text.compare("iomark", "==", "insert") and 11047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.compare("insert", "==", "end-1c")): 11057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Let the default binding (delete next char) take over 11067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not self.executing: 11077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 11087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close() 11097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 11107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 11117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.endoffile = 1 11127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.quit() 11137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 11157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def linefeed_callback(self, event): 11167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Insert a linefeed without entering anything (still autoindented) 11177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.reading: 11187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.insert("insert", "\n") 11197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.see("insert") 11207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1121822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser self.newline_and_indent_event(event) 11227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 11247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def enter_callback(self, event): 11257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.executing and not self.reading: 11267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return # Let the default binding (insert '\n') take over 11277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If some text is selected, recall the selection 11287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # (but only if this before the I/O mark) 11297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 11307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sel = self.text.get("sel.first", "sel.last") 11317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if sel: 11327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("sel.last", "<=", "iomark"): 1133a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.recall(sel, event) 11347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 11367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 11377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If we're strictly before the line containing iomark, recall 11387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # the current line, less a leading prompt, less leading or 11397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # trailing whitespace 11407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("insert", "<", "iomark linestart"): 11417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Check if there's a relevant stdin range -- if so, use it 11427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer prev = self.text.tag_prevrange("stdin", "insert") 11437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if prev and self.text.compare("insert", "<", prev[1]): 1144a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.recall(self.text.get(prev[0], prev[1]), event) 11457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer next = self.text.tag_nextrange("stdin", "insert") 11477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if next and self.text.compare("insert lineend", ">=", next[0]): 1148a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.recall(self.text.get(next[0], next[1]), event) 11497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11504ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser # No stdin mark -- just get the current line, less any prompt 1151b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser indices = self.text.tag_nextrange("console", "insert linestart") 1152b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser if indices and \ 1153b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser self.text.compare(indices[0], "<=", "insert linestart"): 1154b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser self.recall(self.text.get(indices[1], "insert lineend"), event) 1155b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser else: 1156b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser self.recall(self.text.get("insert linestart", "insert lineend"), event) 11577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 1158822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser # If we're between the beginning of the line and the iomark, i.e. 11594ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser # in the prompt area, move to the end of the prompt 1160822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser if self.text.compare("insert", "<", "iomark"): 11614ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser self.text.mark_set("insert", "iomark") 11627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If we're in the current input and there's only whitespace 11637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # beyond the cursor, erase that whitespace first 11647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = self.text.get("insert", "end-1c") 1165837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser if s and not s.strip(): 11667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.delete("insert", "end-1c") 11677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If we're in the current input before its last line, 11687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # insert a newline right at the insert point 11697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.compare("insert", "<", "end-1c linestart"): 1170822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser self.newline_and_indent_event(event) 11717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # We're in the last line; append a newline and submit it 11737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "end-1c") 11747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.reading: 11757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.insert("insert", "\n") 11767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.see("insert") 11777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1178822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser self.newline_and_indent_event(event) 11797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_add("stdin", "iomark", "end-1c") 11807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.update_idletasks() 11817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.reading: 11827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.quit() # Break out of recursive mainloop() in raw_input() 11837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 11847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.runit() 11857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 11867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1187a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser def recall(self, s, event): 1188cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser # remove leading and trailing empty or whitespace lines 1189cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser s = re.sub(r'^\s*\n', '' , s) 1190cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser s = re.sub(r'\n\s*$', '', s) 1191cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser lines = s.split('\n') 1192a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.undo_block_start() 1193a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser try: 1194a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.tag_remove("sel", "1.0", "end") 1195a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.mark_set("insert", "end-1c") 1196cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser prefix = self.text.get("insert linestart", "insert") 1197cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser if prefix.rstrip().endswith(':'): 11988fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser self.newline_and_indent_event(event) 1199cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser prefix = self.text.get("insert linestart", "insert") 1200cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser self.text.insert("insert", lines[0].strip()) 12018fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser if len(lines) > 1: 1202cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0) 1203cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser new_base_indent = re.search(r'^([ \t]*)', prefix).group(0) 12048fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser for line in lines[1:]: 1205cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser if line.startswith(orig_base_indent): 1206cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser # replace orig base indentation with new indentation 1207cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser line = new_base_indent + line[len(orig_base_indent):] 1208cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser self.text.insert('insert', '\n'+line.rstrip()) 1209a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser finally: 1210a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.see("insert") 1211a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser self.text.undo_block_stop() 12127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def runit(self): 12147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = self.text.get("iomark", "end-1c") 12157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Strip off last newline and surrounding whitespace. 12167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # (To allow you to hit return twice to end a statement.) 12177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = len(line) 12187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer while i > 0 and line[i-1] in " \t": 12197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = i-1 12207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if i > 0 and line[i-1] == "\n": 12217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = i-1 12227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer while i > 0 and line[i-1] in " \t": 12237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = i-1 12247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = line[:i] 12257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer more = self.interp.runsource(line) 12267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_stack_viewer(self, event=None): 12285d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey if self.interp.rpcclt: 12295d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey return self.interp.remote_stack_viewer() 12307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 12317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.last_traceback 12327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 12337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror("No stack trace", 12347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "There is no stack trace yet.\n" 12357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "(sys.last_traceback is not defined)", 12367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.text) 12377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 1238d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna from idlelib.StackViewer import StackBrowser 12397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sv = StackBrowser(self.root, self.flist) 12407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12411061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser def view_restart_mark(self, event=None): 12421061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser self.text.see("iomark") 12431061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser self.text.see("restart") 12441061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser 12451061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser def restart_shell(self, event=None): 1246b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy "Callback for Run/Restart Shell Cntl-F6" 1247b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy self.interp.restart_subprocess(with_cwd=True) 12481061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser 12497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def showprompt(self): 12507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.resetoutput() 12517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 12527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = str(sys.ps1) 12537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 12547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = "" 12557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.console.write(s) 12567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "end-1c") 12575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.set_line_and_column() 1258dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser self.io.reset_undo() 12597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def resetoutput(self): 12617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer source = self.text.get("iomark", "end-1c") 12627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.history: 12637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.history.history_store(source) 12647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.text.get("end-2c") != "\n": 12657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.insert("end-1c", "\n") 12667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("iomark", "end-1c") 12675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.set_line_and_column() 12687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer sys.stdout.softspace = 0 12697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def write(self, s, tags=()): 1271003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser try: 1272003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.text.mark_gravity("iomark", "right") 1273003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser OutputWindow.write(self, s, tags, "iomark") 1274003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser self.text.mark_gravity("iomark", "left") 1275003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser except: 1276003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser pass 12777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.canceled: 12787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.canceled = 0 12797f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser if not use_subprocess: 12807f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser raise KeyboardInterrupt 12817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 12825018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov def rmenu_check_cut(self): 12835018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov try: 12845018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov if self.text.compare('sel.first', '<', 'iomark'): 12855018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov return 'disabled' 12865018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov except TclError: # no selection, so the index 'sel.first' doesn't exist 12875018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov return 'disabled' 12885018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov return super(PyShell, self).rmenu_check_cut() 12895018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov 12905018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov def rmenu_check_paste(self): 12915018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov if self.text.compare('insert', '<', 'iomark'): 12925018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov return 'disabled' 12935018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov return super(PyShell, self).rmenu_check_paste() 12945018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov 12959abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoFile(io.TextIOBase): 12967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1297bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis def __init__(self, shell, tags, encoding=None): 12987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.shell = shell 12997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.tags = tags 13005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey self.softspace = 0 13019abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self._encoding = encoding 13029abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13039abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka @property 13049abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def encoding(self): 13059abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return self._encoding 13069abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13079abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka @property 13089abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def name(self): 13099abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return '<%s>' % self.tags 13109abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13119abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def isatty(self): 13129abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return True 13139abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13149abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13159abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoOutputFile(PseudoFile): 13169abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13179abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def writable(self): 13189abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return True 13197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 13207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def write(self, s): 13219abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if self.closed: 13229abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka raise ValueError("write to closed file") 1323f8fc674f0bc1819a85e64e1f3174b682260adab6Terry Jan Reedy if not isinstance(s, (basestring, bytearray)): 1324f8fc674f0bc1819a85e64e1f3174b682260adab6Terry Jan Reedy raise TypeError('must be string, not ' + type(s).__name__) 13259abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return self.shell.write(s, self.tags) 13267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 13277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 13289abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoInputFile(PseudoFile): 13297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 13309abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def __init__(self, shell, tags, encoding=None): 13319abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka PseudoFile.__init__(self, shell, tags, encoding) 13329abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self._line_buffer = '' 13337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 13349abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def readable(self): 13359abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return True 1336e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis 13379abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def read(self, size=-1): 13389abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if self.closed: 13399abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka raise ValueError("read from closed file") 13409abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if size is None: 13419abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka size = -1 13429abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka elif not isinstance(size, int): 13439abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka raise TypeError('must be int, not ' + type(size).__name__) 13449abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka result = self._line_buffer 13459abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self._line_buffer = '' 13469abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if size < 0: 13479abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka while True: 13489abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka line = self.shell.readline() 13499abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if not line: break 13509abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka result += line 13519abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka else: 13529abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka while len(result) < size: 13539abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka line = self.shell.readline() 13549abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if not line: break 13559abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka result += line 13569abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self._line_buffer = result[size:] 13579abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka result = result[:size] 13589abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return result 13599abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka 13609abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka def readline(self, size=-1): 13619abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if self.closed: 13629abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka raise ValueError("read from closed file") 13639abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if size is None: 13649abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka size = -1 13659abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka elif not isinstance(size, int): 13669abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka raise TypeError('must be int, not ' + type(size).__name__) 13679abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka line = self._line_buffer or self.shell.readline() 13689abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka if size < 0: 13699abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka size = len(line) 13709abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka self._line_buffer = line[size:] 13719abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka return line[:size] 1372e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis 137353dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy def close(self): 137453dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy self.shell.close() 137553dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy 1376969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser 13777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\ 13787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 137911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle [-deins] [-t title] [file]* 138011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser idle [-dns] [-t title] (-c cmd | -r file) [arg]* 138111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser idle [-dns] [-t title] - [arg]* 13826655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 1383f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -h print this help message and exit 13848f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser -n run IDLE without a subprocess (see Help/IDLE Help for details) 1385f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1386f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration: 1387f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1388f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -e open an edit window 1389f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -i open a shell window 1390f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1391f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell: 1392f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1393f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -c cmd run the command in a shell, or 1394f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -r file run script from file 1395f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1396f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -d enable the debugger 1397f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else 1398f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser -t title set title of shell window 1399f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1400f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used. 1401f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1402f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:]. 1403f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1404f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples: 14057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1406f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle 1407f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open an edit window or shell depending on IDLE's configuration. 140896d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser 1409f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py 1410f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Edit the files, also open a shell if configured to start with shell. 1411f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1412f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py 1413f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell 1414f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser window with the title "Baz". 1415f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1416f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo" 1417f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open a shell window and run the command, passing "-c" in sys.argv[0] 1418f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser and "foo" in sys.argv[1]. 1419f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1420f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World" 1421f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open a shell window, run a startup script, enable the debugger, and 1422f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in 1423f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv[1]. 1424f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 1425f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar" 1426f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser Open a shell window, run the script piped in, passing '' in sys.argv[0] 1427f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser and "foobar" in sys.argv[1]. 14287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer""" 14297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1430969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main(): 1431f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser global flist, root, use_subprocess 1432f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser 14338f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser use_subprocess = True 143434d0c66ef2bcfae00beb9f2b14e393cd00f499e4Roger Serwy enable_shell = False 1435f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = False 1436f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser debug = False 1437969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser cmd = None 1438969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser script = None 1439f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser startup = False 1440969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser try: 14418f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") 1442969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser except getopt.error, msg: 1443969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.stderr.write("Error: %s\n" % str(msg)) 1444969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.stderr.write(usage_msg) 1445969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.exit(2) 1446969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser for o, a in opts: 1447969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-c': 1448969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser cmd = a 1449f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1450969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-d': 1451f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser debug = True 1452f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1453969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-e': 1454f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = True 1455f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if o == '-h': 1456f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.stdout.write(usage_msg) 1457f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.exit() 1458f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if o == '-i': 1459f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 14608f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser if o == '-n': 14618f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser use_subprocess = False 1462969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-r': 1463969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser script = a 1464f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if os.path.isfile(script): 1465f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser pass 1466f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser else: 1467f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser print "No script file: ", script 1468f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.exit() 1469f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1470969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-s': 1471f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser startup = True 1472f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1473969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if o == '-t': 1474969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser PyShell.shell_title = a 1475f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1476f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if args and args[0] == '-': 1477f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser cmd = sys.stdin.read() 1478f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_shell = True 1479f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # process sys.argv and sys.path: 1480969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser for i in range(len(sys.path)): 1481969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser sys.path[i] = os.path.abspath(sys.path[i]) 1482f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if args and args[0] == '-': 1483f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv = [''] + args[1:] 1484f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif cmd: 1485f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv = ['-c'] + args 1486f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif script: 1487f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.argv = [script] + args 1488f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif args: 1489f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = True 1490f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser pathx = [] 1491969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser for filename in args: 1492969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser pathx.append(os.path.dirname(filename)) 1493f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser for dir in pathx: 1494f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser dir = os.path.abspath(dir) 1495d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna if dir not in sys.path: 1496f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser sys.path.insert(0, dir) 1497ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser else: 1498ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser dir = os.getcwd() 1499ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser if not dir in sys.path: 1500ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser sys.path.insert(0, dir) 1501f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # check the IDLE settings configuration (but command line overrides) 1502f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser edit_start = idleConf.GetOption('main', 'General', 15036655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser 'editor-on-startup', type='bool') 1504f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser enable_edit = enable_edit or edit_start 150534d0c66ef2bcfae00beb9f2b14e393cd00f499e4Roger Serwy enable_shell = enable_shell or not enable_edit 1506f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # start editor and/or shell windows: 1507969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root = Tk(className="Idle") 150819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1509969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser fixwordbreaks(root) 1510969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root.withdraw() 1511969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser flist = PyShellFileList(root) 151219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren macosxSupport.setupApp(root, flist) 151319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1514f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if enable_edit: 1515f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if not (cmd or script): 15167c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov for filename in args[:]: 15177c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov if flist.open(filename) is None: 15187c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov # filename is a directory actually, disconsider it 15197c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov args.remove(filename) 1520f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if not args: 1521f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser flist.new() 1522af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if enable_shell: 152319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren shell = flist.open_shell() 152419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren if not shell: 1525af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser return # couldn't open shell 152619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 152719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren if macosxSupport.runningAsOSXApp() and flist.dict: 152819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren # On OSX: when the user has double-clicked on a file that causes 15294f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters # IDLE to be launched the shell window will open just in front of 15304f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters # the file she wants to see. Lower the interpreter window when 153119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren # there are open files. 153219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren shell.top.lower() 153319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 1534f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell = flist.pyshell 1535f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser # handle remaining options: 1536f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if debug: 1537f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.open_debugger() 1538969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if startup: 1539969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser filename = os.environ.get("IDLESTARTUP") or \ 1540969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser os.environ.get("PYTHONSTARTUP") 1541969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser if filename and os.path.isfile(filename): 1542f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.execfile(filename) 1543af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser if shell and cmd or script: 1544f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.runcommand("""if 1: 1545f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser import sys as _sys 154670a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald _sys.argv = %r 1547f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser del _sys 154870a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald \n""" % (sys.argv,)) 1549f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser if cmd: 1550f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.execsource(cmd) 1551f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser elif script: 155211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser shell.interp.prepend_syspath(script) 1553f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser shell.interp.execfile(script) 155419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren 15552a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily # Check for problematic OS X Tk versions and print a warning message 15562a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily # in the IDLE shell window; this is less intrusive than always opening 15572a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily # a separate window. 15582a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily tkversionwarning = macosxSupport.tkVersionWarning(root) 15592a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily if tkversionwarning: 15602a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily shell.interp.runcommand(''.join(("print('", tkversionwarning, "')"))) 15612a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily 1562eaa7e7825e9f4b211bc104cfde6cc951f9dcb94eTerry Jan Reedy while flist.inversedict: # keep IDLE running while files are open. 1563eaa7e7825e9f4b211bc104cfde6cc951f9dcb94eTerry Jan Reedy root.mainloop() 1564969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser root.destroy() 1565969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser 15667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__": 15679e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser sys.modules['PyShell'] = sys.modules['__main__'] 15687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer main() 1569