PyShell.py revision dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670
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
1419302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussorenimport macosxSupport
157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport linecache
177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom code import InteractiveInterpreter
187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
192303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaisertry:
202303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    from Tkinter import *
212303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiserexcept ImportError:
222303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    print>>sys.__stderr__, "** IDLE can't import Tkinter.  " \
232303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser                           "Your Python may not be configured for Tk. **"
242303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    sys.exit(1)
257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport tkMessageBox
267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom EditorWindow import EditorWindow, fixwordbreaks
287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom FileList import FileList
297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom ColorDelegator import ColorDelegator
307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom UndoDelegator import UndoDelegator
31969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserfrom OutputWindow import OutputWindow
329930061ce28b1fc60d267ae3474c74a41e655cd5Steven M. Gavafrom configHandler import idleConf
337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport idlever
347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport rpc
367f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiserimport Debugger
37ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiserimport RemoteDebugger
385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
39b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_"
4024d7e0cbb8b978738f223d4bb6cb184054d72e18Kurt B. KaiserLOCALHOST = '127.0.0.1'
41b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser
42a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry:
43a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    from signal import SIGTERM
44a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError:
45a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    SIGTERM = 15
46a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser
4749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# Override warnings module to write to warning_stream.  Initialize to send IDLE
4849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# internal warnings to the console.  ScriptBinding.check_syntax() will
4949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# temporarily redirect the stream to the shell window to display warnings when
5049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# checking user's code.
5149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiserglobal warning_stream
5249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiserwarning_stream = sys.__stderr__
535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teytry:
545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    import warnings
555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyexcept ImportError:
565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    pass
575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyelse:
585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def idle_showwarning(message, category, filename, lineno):
5949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        file = warning_stream
6049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        try:
6149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser            file.write(warnings.formatwarning(message, category, filename, lineno))
6249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        except IOError:
6349a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser            pass  ## file (probably __stderr__) is invalid, warning dropped.
645d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    warnings.showwarning = idle_showwarning
6549a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def idle_formatwarning(message, category, filename, lineno):
6649a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        """Format warnings the IDLE way"""
6749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        s = "\nWarning (from warnings module):\n"
6849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        s += '  File \"%s\", line %s\n' % (filename, lineno)
6949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        line = linecache.getline(filename, lineno).strip()
7049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        if line:
7149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser            s += "    %s\n" % line
7249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        s += "%s: %s\n>>> " % (category.__name__, message)
7349a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        return s
7449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    warnings.formatwarning = idle_formatwarning
755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
76f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiserdef extended_linecache_checkcache(filename=None,
77f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser                                  orig_checkcache=linecache.checkcache):
7845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """Extend linecache.checkcache to preserve the <pyshell#...> entries
7945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
80f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    Rather than repeating the linecache code, patch it to save the
81f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    <pyshell#...> entries, call the original linecache.checkcache()
82f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    (which destroys them), and then restore the saved entries.
83f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser
84f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    orig_checkcache is bound at definition time to the original
85f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    method, allowing it to be patched.
8645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
8745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """
887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache = linecache.cache
897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    save = {}
907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    for filename in cache.keys():
917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if filename[:1] + filename[-1:] == '<>':
927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            save[filename] = cache[filename]
937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    orig_checkcache()
947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache.update(save)
956655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
96818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache():
97818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache
987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
1007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow):
101183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    "Regular text edit window in IDLE, supports breakpoints"
10245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
1037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, *args):
10445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.breakpoints = []
105931237e2e66975c54e2ac6c5e503ee2992a22bcfRaymond Hettinger        EditorWindow.__init__(self, *args)
1067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
10745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
1087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
1097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
110bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
111bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                           'breakpoints.lst')
112a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        # whenever a file is changed, restore breakpoints
113a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if self.io.filename: self.restore_file_breaks()
114bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        def filename_changed_hook(old_hook=self.io.filename_change_hook,
115bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                  self=self):
116a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            self.restore_file_breaks()
117a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            old_hook()
118a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.io.set_filename_change_hook(filename_changed_hook)
119a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
12045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
12145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
1227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
123a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint(self, lineno):
12445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
12545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
126a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
12745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
12845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            i = self.breakpoints.index(lineno)
129a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except ValueError:  # only add if missing, i.e. do once
13045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.append(lineno)
13145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:    # update the subprocess debugger
13245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
13345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.set_breakpoint_here(filename, lineno)
13445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except: # but debugger may not be active right now....
13545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
1367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
137a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint_here(self, event=None):
138a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
139a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        filename = self.io.filename
140a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if not filename:
141a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            text.bell()
142a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            return
143a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        lineno = int(float(text.index("insert")))
144a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.set_breakpoint(lineno)
145a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
146669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser    def clear_breakpoint_here(self, event=None):
14745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
14845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
14945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if not filename:
15045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.bell()
151669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser            return
15245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        lineno = int(float(text.index("insert")))
15345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
15445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.remove(lineno)
15545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
15645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
15745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text.tag_remove("BREAK", "insert linestart",\
15845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                        "insert lineend +1char")
15945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
16045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
16145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.clear_breakpoint_here(filename, lineno)
16245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
16345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
16445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
16545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def clear_file_breaks(self):
16645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if self.breakpoints:
16745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text = self.text
16845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            filename = self.io.filename
16945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            if not filename:
17045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                text.bell()
17145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                return
17245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints = []
17345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.tag_remove("BREAK", "1.0", END)
17445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            try:
17545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug = self.flist.pyshell.interp.debugger
17645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug.clear_file_breaks(filename)
17745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            except:
17845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                pass
17945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
180a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def store_file_breaks(self):
181bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Save breakpoints when file is saved"
182bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
183bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be run.  The breaks are saved at that time.  If we introduce
184bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     a temporary file save feature the save breaks functionality
185bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     needs to be re-verified, since the breaks at the time the
186bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     temp file is created may differ from the breaks at the last
1877f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     permanent save of the file.  Currently, a break introduced
1887f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     after a save will be effective, but not persistent.
1897f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     This is necessary to keep the saved breaks synched with the
1907f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     saved file.
191bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #
192bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Breakpoints are set as tagged ranges in the text.  Certain
193bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     kinds of edits cause these ranges to be deleted: Inserting
194bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     or deleting a line just before a breakpoint, and certain
195bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     deletions prior to a breakpoint.  These issues need to be
196bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     investigated and understood.  It's not clear if they are
197bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Tk issues or IDLE issues, or whether they can actually
198bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be fixed.  Since a modified file has to be saved before it is
199bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     run, and since self.breakpoints (from which the subprocess
200bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     debugger is loaded) is updated during the save, the visible
201bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     breaks stay synched with the subprocess even if one of these
202bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     unexpected breakpoint deletions occurs.
203bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
204bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
205a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        try:
206bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
207a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except IOError:
208bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = []
209bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        new_file = open(self.breakpointPath,"w")
210a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        for line in lines:
211bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            if not line.startswith(filename + '='):
212a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey                new_file.write(line)
213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.update_breakpoints()
214bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if breaks:
216bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            new_file.write(filename + '=' + str(breaks) + '\n')
217a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        new_file.close()
218a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
219a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def restore_file_breaks(self):
220a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.text.update()   # this enables setting "BREAK" tags to be visible
221bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
222bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if filename is None:
223bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            return
22469371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey        if os.path.isfile(self.breakpointPath):
225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
22669371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey            for line in lines:
227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                if line.startswith(filename + '='):
2286655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                    breakpoint_linenumbers = eval(line[len(filename)+1:])
22969371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                    for breakpoint_linenumber in breakpoint_linenumbers:
23069371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                        self.set_breakpoint(breakpoint_linenumber)
231a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
232bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def update_breakpoints(self):
233bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Retrieves all the breakpoints in the current window"
234a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
235bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        ranges = text.tag_ranges("BREAK")
236bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        linenumber_list = self.ranges_to_linenumbers(ranges)
237bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpoints = linenumber_list
238bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
239bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def ranges_to_linenumbers(self, ranges):
240bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        lines = []
241bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        for index in range(0, len(ranges), 2):
242bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lineno = int(float(ranges[index]))
243bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            end = int(float(ranges[index+1]))
244bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            while lineno < end:
245bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lines.append(lineno)
246bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lineno += 1
247bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        return lines
248bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
24911220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently
250bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#    def saved_change_hook(self):
251bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        "Extend base method - clear breaks if module is modified"
252bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        if not self.get_saved():
253bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#            self.clear_file_breaks()
254bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        EditorWindow.saved_change_hook(self)
25545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
25645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def _close(self):
25745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        "Extend base method - clear breaks when module is closed"
25845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.clear_file_breaks()
25945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        EditorWindow._close(self)
2606655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
2617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList):
263183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    "Extend base class: IDLE supports a shell and breakpoints"
2647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
265183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    # override FileList's class variable, instances return PyShellEditorWindow
266183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    # instead of EditorWindow when new edit windows are created.
2677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    EditorWindow = PyShellEditorWindow
2687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    pyshell = None
2707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_shell(self, event=None):
2727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.pyshell:
273183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            self.pyshell.top.wakeup()
2747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
2757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell = PyShell(self)
276af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if self.pyshell:
277af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                if not self.pyshell.begin():
278af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                    return None
2797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.pyshell
2807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator):
28383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: colorizer for the shell window itself"
2846655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
285b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def __init__(self):
286b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.__init__(self)
287b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.LoadTagDefs()
2887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recolorize_main(self):
2907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_remove("TODO", "1.0", "iomark")
2917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_add("SYNC", "1.0", "iomark")
2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ColorDelegator.recolorize_main(self)
2936655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
294b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def LoadTagDefs(self):
295b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.LoadTagDefs(self)
296b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        theme = idleConf.GetOption('main','Theme','name')
297b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.tagdefs.update({
298b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdin": {'background':None,'foreground':None},
299b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdout": idleConf.GetHighlight(theme, "stdout"),
300b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stderr": idleConf.GetHighlight(theme, "stderr"),
301b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "console": idleConf.GetHighlight(theme, "console"),
302b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            None: idleConf.GetHighlight(theme, "normal"),
303b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        })
3047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator):
30683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: forbid insert/delete before the I/O mark"
3077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def insert(self, index, chars, tags=None):
3097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
3107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index, "<", "iomark"):
3117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
3127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.insert(self, index, chars, tags)
3167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def delete(self, index1, index2=None):
3187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
3197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index1, "<", "iomark"):
3207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
3217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.delete(self, index1, index2)
3257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
32667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
32767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient):
32867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
32967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser    def handle_EOF(self):
33067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        "Override the base class - just re-raise EOFError"
33167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        raise EOFError
33267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
3338d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser
3347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter):
3357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, tkconsole):
3377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole = tkconsole
3387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        locals = sys.modules['__main__'].__dict__
3397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.__init__(self, locals=locals)
34094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = None
3416f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
34262df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        self.subprocess_arglist = self.build_subprocess_arglist()
3437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
34463857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    port = 8833
3455d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcclt = None
3465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcpid = None
3475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
3486655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    def spawn_subprocess(self):
34962df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        args = self.subprocess_arglist
350b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
35163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser
352f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds    def build_subprocess_arglist(self):
3532398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        w = ['-W' + s for s in sys.warnoptions]
354d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl        if 1/2 > 0: # account for new division
355d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl            w.append('-Qnew')
3562398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # Maybe IDLE is installed and is being accessed via sys.path,
3572398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # or maybe it's not installed and the idle.py script is being
3582398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # run from the IDLE source directory.
35962df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
36062df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser                                       default=False, type='bool')
3612398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        if __name__ == 'idlelib.PyShell':
36270a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
363f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds        else:
36470a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            command = "__import__('run').main(%r)" % (del_exitf,)
365b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        if sys.platform[:3] == 'win' and ' ' in sys.executable:
366b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            # handle embedded space in path by quoting the argument
367b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = '"%s"' % sys.executable
368b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        else:
369b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = sys.executable
370b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        return [decorated_exec] + w + ["-c", command, str(self.port)]
371f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds
37263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def start_subprocess(self):
373af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        # spawning first avoids passing a listening socket to the subprocess
374af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        self.spawn_subprocess()
375af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        #time.sleep(20) # test to simulate GUI not accepting connection
37624d7e0cbb8b978738f223d4bb6cb184054d72e18Kurt B. Kaiser        addr = (LOCALHOST, self.port)
3778dcdb77132563c734c228e815498c47e487f95cfKurt B. Kaiser        # Idle starts listening for connection on localhost
3785db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        for i in range(3):
3795d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            time.sleep(i)
3805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            try:
38167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.rpcclt = MyRPCClient(addr)
3825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                break
3835d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            except socket.error, err:
384af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                pass
3855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
386af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_port_binding_error()
387af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
388b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        # Accept the connection from the Python execution server
389af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        self.rpcclt.listening_sock.settimeout(10)
390af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
391af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
392af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except socket.timeout, err:
393af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
394af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
395969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdin", self.tkconsole)
396969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdout", self.tkconsole.stdout)
397969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stderr", self.tkconsole.stderr)
3985d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcclt.register("flist", self.tkconsole.flist)
3998cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser        self.rpcclt.register("linecache", linecache)
4009f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.rpcclt.register("interp", self)
401f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
4025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.poll_subprocess()
403af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
4045d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
40563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def restart_subprocess(self):
4066f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if self.restarting:
407af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return self.rpcclt
4086f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = True
40963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        # close only the subprocess debugger
41045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        debug = self.getdebugger()
41145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
412003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            try:
4139ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser                # Only close subprocess debugger, don't unregister gui_adap!
414003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
415003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            except:
416003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                pass
417003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # Kill subprocess, spawn a new one, accept connection.
418a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
419a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
4207f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console = self.tkconsole
4216f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        was_executing = console.executing
4227f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.executing = False
42363857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.spawn_subprocess()
424af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
425af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
426af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except socket.timeout, err:
427af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
428af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
429f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
4301061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        # annotate restart in shell window and mark it
4314cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        console.text.delete("iomark", "end-1c")
4326f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if was_executing:
4336f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.write('\n')
4346f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.showprompt()
4351061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        halfbar = ((int(console.width) - 16) // 2) * '='
4361061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.write(halfbar + ' RESTART ' + halfbar)
4371061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_set("restart", "end-1c")
4381061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_gravity("restart", "left")
4397f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.showprompt()
440003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # restart subprocess debugger
44145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
4429ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser            # Restarted debugger connects to current instance of debug GUI
44363857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
44445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            # reload remote debugger breakpoints for all PyShellEditWindows
44545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.load_breakpoints()
4466f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
447af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
44845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
449003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def __request_interrupt(self):
450a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
451003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
452003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def interrupt_subprocess(self):
453a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        threading.Thread(target=self.__request_interrupt).start()
454003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
455a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def kill_subprocess(self):
456af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
457af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.close()
458af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except AttributeError:  # no socket
459af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            pass
460a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
461a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.executing = False
462a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt = None
46311c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
464a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def unix_terminate(self):
465a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        "UNIX: make sure subprocess is terminated and collect status"
466a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        if hasattr(os, 'kill'):
467a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            try:
468a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                os.kill(self.rpcpid, SIGTERM)
469a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            except OSError:
470a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                # process already terminated:
471a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                return
472a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            else:
473a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                try:
474a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    os.waitpid(self.rpcpid, 0)
475a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                except OSError:
476a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    return
47711c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
478f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    def transfer_path(self):
479f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.runcommand("""if 1:
480f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        import sys as _sys
48170a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald        _sys.path = %r
482f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        del _sys
48370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald        \n""" % (sys.path,))
484f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
4855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    active_seq = None
4865d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4875d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def poll_subprocess(self):
4885d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        clt = self.rpcclt
4895d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if clt is None:
4905d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
491003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
492a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            response = clt.pollresponse(self.active_seq, wait=0.05)
493a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        except (EOFError, IOError, KeyboardInterrupt):
494a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # lost connection or subprocess terminated itself, restart
495a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # [the KBI is from rpc.SocketIO.handle_EOF()]
49667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.tkconsole.closing:
49767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                return
498003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = None
499003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.restart_subprocess()
5005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if response:
5015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.resetoutput()
5025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.active_seq = None
5035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            how, what = response
504bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            console = self.tkconsole.console
5055d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            if how == "OK":
5065d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if what is not None:
50770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald                    print >>console, repr(what)
5085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "EXCEPTION":
5095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
5105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                    self.remote_stack_viewer()
5115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "ERROR":
5120930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
5130930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                print >>sys.__stderr__, errmsg, what
514bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                print >>console, errmsg, what
515bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            # we received a response to the currently active seq number:
516d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser            try:
517d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                self.tkconsole.endexecuting()
518d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser            except AttributeError:  # shell may have closed
519d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                pass
52088957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        # Reschedule myself
52188957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        if not self.tkconsole.closing:
52288957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser            self.tkconsole.text.after(self.tkconsole.pollinterval,
52388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser                                      self.poll_subprocess)
5245d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
52545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    debugger = None
52645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
52745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def setdebugger(self, debugger):
52845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.debugger = debugger
52945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
53045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def getdebugger(self):
53145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        return self.debugger
53245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
5339f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser    def open_remote_stack_viewer(self):
5349f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """Initiate the remote stack viewer from a separate thread.
5359f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
5369f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        This method is called from the subprocess, and by returning from this
5379f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        method we allow the subprocess to unblock.  After a bit the shell
5389f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        requests the subprocess to open the remote stack viewer which returns a
5399f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        static object looking at the last exceptiopn.  It is queried through
5409f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        the RPC mechanism.
5419f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
5429f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """
5439f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.tkconsole.text.after(300, self.remote_stack_viewer)
5449f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        return
5459f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
5465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def remote_stack_viewer(self):
5475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        import RemoteObjectBrowser
548a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
5495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if oid is None:
5505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.root.bell()
5515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
5525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
5535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        from TreeWidget import ScrolledCanvas, TreeNode
5545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        top = Toplevel(self.tkconsole.root)
55573360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        theme = idleConf.GetOption('main','Theme','name')
55673360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        background = idleConf.GetHighlight(theme, 'normal')['background']
55773360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        sc = ScrolledCanvas(top, bg=background, highlightthickness=0)
5585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc.frame.pack(expand=1, fill="both")
5595d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node = TreeNode(sc.canvas, None, item)
5605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node.expand()
5615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # XXX Should GC the remote tree when closing the window
5625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
5637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    gid = 0
5647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execsource(self, source):
56683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Like runsource() but assumes complete exec source"
5677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.execfile(filename, source)
5697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execfile(self, filename, source=None):
57183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Execute an existing file"
5727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if source is None:
5737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            source = open(filename, "r").read()
5747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
5757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            code = compile(source, filename, "exec")
5767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except (OverflowError, SyntaxError):
5777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
5787f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            tkerr = self.tkconsole.stderr
5797f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, '*** Error in script or command!\n'
5807f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, 'Traceback (most recent call last):'
5817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            InteractiveInterpreter.showsyntaxerror(self, filename)
5826e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.showprompt()
5837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
5847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runcode(code)
5857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runsource(self, source):
58783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method: Stuff the source in the line cache first"
5887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.more = 0
59094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = warnings.filters[:]
59194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        warnings.filterwarnings(action="error", category=SyntaxWarning)
592837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if isinstance(source, types.UnicodeType):
593837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            import IOBinding
594837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            try:
595837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                source = source.encode(IOBinding.encoding)
596837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            except UnicodeError:
597837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.tkconsole.resetoutput()
598cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                self.write("Unsupported characters in input\n")
599837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                return
60094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        try:
601935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser            # InteractiveInterpreter.runsource() calls its runcode() method,
602935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser            # which is overridden (see below)
60394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            return InteractiveInterpreter.runsource(self, source, filename)
60494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        finally:
60594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            if self.save_warnings_filters is not None:
60694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                warnings.filters[:] = self.save_warnings_filters
60794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                self.save_warnings_filters = None
6087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def stuffsource(self, source):
61083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Stuff source in the filename cache"
6117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = "<pyshell#%d>" % self.gid
6127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.gid = self.gid + 1
613837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        lines = source.split("\n")
6147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        linecache.cache[filename] = len(source)+1, 0, lines, filename
6157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return filename
6166655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
61711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser    def prepend_syspath(self, filename):
61811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        "Prepend sys.path with file's directory if not already included"
61911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        self.runcommand("""if 1:
62070a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            _filename = %r
62111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            import sys as _sys
62211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            from os.path import dirname as _dirname
62311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _dir = _dirname(_filename)
62411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            if not _dir in _sys.path:
62511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser                _sys.path.insert(0, _dir)
62611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            del _filename, _sys, _dirname, _dir
62770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            \n""" % (filename,))
62811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser
6297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showsyntaxerror(self, filename=None):
63083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """Extend base class method: Add Colorizing
63183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
63283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        Color the offending position instead of printing it and pointing at it
63383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        with a caret.
63483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
63583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """
6367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.tkconsole.text
6377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        stuff = self.unpackerror()
6386e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        if stuff:
6396e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            msg, lineno, offset, line = stuff
6406e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if lineno == 1:
6416e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark + %d chars" % (offset-1)
6426e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            else:
6436e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark linestart + %d lines + %d chars" % \
6446e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                      (lineno-1, offset-1)
6456e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.tag_add("ERROR", pos)
6466e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.see(pos)
6476e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            char = text.get(pos)
6486e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if char and char in IDENTCHARS:
6496e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                text.tag_add("ERROR", pos + " wordstart", pos)
6507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
6516e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.write("SyntaxError: %s\n" % str(msg))
6527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6536e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.resetoutput()
6546e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            InteractiveInterpreter.showsyntaxerror(self, filename)
6556e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        self.tkconsole.showprompt()
6567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def unpackerror(self):
6587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        type, value, tb = sys.exc_info()
6597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ok = type is SyntaxError
6607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
6617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
6627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                msg, (dummy_filename, lineno, offset, line) = value
663bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                if not offset:
664bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                    offset = 0
6657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except:
6667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                ok = 0
6677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
6687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return msg, lineno, offset, line
6697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
6717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showtraceback(self):
67383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method to reset output properly"
6747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole.resetoutput()
6757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.checklinecache()
6767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.showtraceback(self)
6775d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
6785d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.open_stack_viewer()
6797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def checklinecache(self):
6817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        c = linecache.cache
6827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for key in c.keys():
6837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key[:1] + key[-1:] != "<>":
6847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del c[key]
6857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6865d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def runcommand(self, code):
68783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Run the code without invoking the debugger"
6885d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # The code better not raise an exception!
6895d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
690f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz            self.display_executing_dialog()
6915d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return 0
6925d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.rpcclt:
693a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
6945d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
6955d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            exec code in self.locals
6965d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        return 1
6975d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
6987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runcode(self, code):
69983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
7005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
701003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.restart_subprocess()
7025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.checklinecache()
70394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        if self.save_warnings_filters is not None:
70494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            warnings.filters[:] = self.save_warnings_filters
70594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            self.save_warnings_filters = None
7067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        debugger = self.debugger
7077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
7087f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.tkconsole.beginexecuting()
709dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if not debugger and self.rpcclt is not None:
710dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
711dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                                                        (code,), {})
712dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            elif debugger:
713dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                debugger.run(code, self.locals)
714dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
715dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                exec code in self.locals
716dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser        except SystemExit:
717dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if not self.tkconsole.closing:
718dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                if tkMessageBox.askyesno(
719dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    "Exit?",
720dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    "Do you want to exit altogether?",
721dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    default="yes",
722dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    master=self.tkconsole.text):
723f137e1df2c02f5782c5b0f18a2b3b649f255f63aKurt B. Kaiser                    raise
724dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                else:
725dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.showtraceback()
726dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
727dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                raise
728dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser        except:
729dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if use_subprocess:
730dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                print >>self.tkconsole.stderr, \
731dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                         "IDLE internal error in runcode()"
7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.showtraceback()
733dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                self.tkconsole.endexecuting()
734dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
735dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                if self.tkconsole.canceled:
736dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.tkconsole.canceled = False
737dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    print >>self.tkconsole.stderr, "KeyboardInterrupt"
738dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                else:
739dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.showtraceback()
7407f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        finally:
7417f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
742d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                try:
743d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                    self.tkconsole.endexecuting()
744d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                except AttributeError:  # shell may have closed
745d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                    pass
7467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
74883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
7497f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.tkconsole.stderr.write(s)
7507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
751af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_port_binding_error(self):
752af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
753af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Port Binding Error",
754af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "IDLE can't bind TCP/IP port 8833, which is necessary to "
755af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "communicate with its Python execution server.  Either "
756af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "no networking is installed on this computer or another "
757af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "process (another IDLE?) is using the port.  Run IDLE with the -n "
758af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "command line switch to start without a subprocess and refer to "
759af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Help/IDLE Help 'Running without a subprocess' for further "
760af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "details.",
761af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
762af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
763af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_no_subprocess_error(self):
764af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
765af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Subprocess Startup Error",
766af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "IDLE's subprocess didn't make connection.  Either IDLE can't "
767af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "start a subprocess or personal firewall software is blocking "
768af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "the connection.",
769af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
770af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
771af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_executing_dialog(self):
772af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
773af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Already executing",
774af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "The Python Shell window is already executing a command; "
775af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "please wait until it is finished.",
776af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
777af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
778af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
7797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow):
7807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    shell_title = "Python Shell"
7827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # Override classes
7847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    ColorDelegator = ModifiedColorDelegator
7857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    UndoDelegator = ModifiedUndoDelegator
7867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
787f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # Override menus
788dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    menu_specs = [
789dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("file", "_File"),
790dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("edit", "_Edit"),
7914cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        ("debug", "_Debug"),
7921061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        ("options", "_Options"),
793dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("windows", "_Windows"),
794dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("help", "_Help"),
795dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    ]
7967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
79719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren    if macosxSupport.runningAsOSXApp():
79819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        del menu_specs[-3]
79919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        menu_specs[-2] = ("windows", "_Window")
80019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
80119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
8027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # New classes
8037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    from IdleHistory import History
8047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, flist=None):
8068f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
80767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            ms = self.menu_specs
80867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if ms[2][0] != "shell":
8097ae354846fff616746eeba6d27ccd5c175591caeKurt B. Kaiser                ms.insert(2, ("shell", "She_ll"))
8107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = ModifiedInterpreter(self)
8117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if flist is None:
8127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root = Tk()
8137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            fixwordbreaks(root)
8147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root.withdraw()
8157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist = PyShellFileList(root)
8165afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        OutputWindow.__init__(self, flist, None, None)
8185afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8196af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
8206af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.usetabs = True
8216af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        # indentwidth must be 8 when using tabs.  See note in EditorWindow:
8226af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.indentwidth = 8
8236af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.context_use_ps1 = True
8245afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.text
8267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.configure(wrap="char")
8277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<newline-and-indent>>", self.enter_callback)
8287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
8297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<interrupt-execution>>", self.cancel_callback)
8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<beginning-of-line>>", self.home_callback)
8317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<end-of-file>>", self.eof_callback)
8327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
83357bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser        text.bind("<<toggle-debugger>>", self.toggle_debugger)
8347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
8358f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
8368f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<view-restart>>", self.view_restart_mark)
8378f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<restart-shell>>", self.restart_shell)
8385afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdout = sys.stdout
8407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stderr = sys.stderr
8417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdin = sys.stdin
842bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        import IOBinding
843bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
844bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
845bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.console = PseudoFile(self, "console", IOBinding.encoding)
8465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if not use_subprocess:
8475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdout = self.stdout
8485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stderr = self.stderr
8495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdin = self
8505afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = self.History(self.text)
8525afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
85388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        self.pollinterval = 50  # millisec
8545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
8554d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser    def get_standard_extension_names(self):
8564d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser        return idleConf.GetExtensions(shell_only=True)
8574d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser
858003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    reading = False
859003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    executing = False
860003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    canceled = False
861003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    endoffile = False
862003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    closing = False
8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
86449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def set_warning_stream(self, stream):
865d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro        global warning_stream
866d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro        warning_stream = stream
86749a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser
86849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def get_warning_stream(self):
86949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        return warning_stream
87049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser
8717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def toggle_debugger(self, event=None):
8727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
8737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("Don't debug now",
8747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "You can only toggle the debugger when idle",
8757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.set_debugger_indicator()
8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
8787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db = self.interp.getdebugger()
8807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if db:
8817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.close_debugger()
8827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
8837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.open_debugger()
8847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def set_debugger_indicator(self):
8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.setvar("<<toggle-debugger>>", not not db)
8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8891061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def toggle_jit_stack_viewer(self, event=None):
8907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass # All we need is the variable
8917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close_debugger(self):
8937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
8947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if db:
8957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.interp.setdebugger(None)
8967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db.close()
897ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser            if self.interp.rpcclt:
898ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.console.write("[DEBUG OFF]\n")
9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.ps1 = ">>> "
9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
9037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.set_debugger_indicator()
9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_debugger(self):
9065d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
9077f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
9087f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                           self)
9097f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
9107f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = Debugger.Debugger(self)
9117f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.interp.setdebugger(dbg_gui)
9127f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        dbg_gui.load_breakpoints()
9135d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sys.ps1 = "[DEBUG ON]\n>>> "
9145d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
9155d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_debugger_indicator()
9165d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
9177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def beginexecuting(self):
918ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser        "Helper for ModifiedInterpreter"
9197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
9207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 1
9217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def endexecuting(self):
92383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Helper for ModifiedInterpreter"
9247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 0
9257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.canceled = 0
9265d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
9277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close(self):
92983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow.close()"
9307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
931003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = tkMessageBox.askokcancel(
9327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Kill?",
933003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                "The program is still running!\n Do you want to kill it?",
9347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                default="ok",
9357f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                parent=self.text)
936003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            if response == False:
9377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "cancel"
9385c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if self.reading:
9395c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.quit()
9405c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        self.canceled = True
94167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.closing = True
94267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        # Wait for poll_subprocess() rescheduling to stop
94367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.text.after(2 * self.pollinterval, self.close2)
94488957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser
94588957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser    def close2(self):
94688957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        return EditorWindow.close(self)
9477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def _close(self):
94983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow._close(), shut down debugger and execution server"
9507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.close_debugger()
9517f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
9527f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.kill_subprocess()
9537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Restore std streams
9547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout = self.save_stdout
9557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stderr = self.save_stderr
9567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdin = self.save_stdin
9577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Break cycles
9587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = None
9597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = None
9607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.flist.pyshell = None
9617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = None
96283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        EditorWindow._close(self)
9637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def ispythonsource(self, filename):
96583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override EditorWindow method: never remove the colorizer"
966837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def short_title(self):
9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.shell_title
9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
97194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser    COPYRIGHT = \
9728f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser          'Type "copyright", "credits" or "license()" for more information.'
97394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser
974220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    firewallmessage = """
975220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    ****************************************************************
976220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    Personal firewall software may warn about the connection IDLE
977220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    makes to its subprocess using this computer's internal loopback
978220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    interface.  This connection is not visible on any external
979220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    interface and no data is sent to or received from the Internet.
980220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    ****************************************************************
981220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    """
982220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser
9837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def begin(self):
9847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
9857f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
9867f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = ''
987af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            client = self.interp.start_subprocess()
988af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if not client:
989af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                self.close()
9907663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser                return False
9917f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
9927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = "==== No Subprocess ===="
993220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser        self.write("Python %s on %s\n%s\n%s\nIDLE %s      %s\n" %
99494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                   (sys.version, sys.platform, self.COPYRIGHT,
995220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser                    self.firewallmessage, idlever.IDLE_VERSION, nosub))
9967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.showprompt()
9977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import Tkinter
998af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        Tkinter._default_root = None # 03Jan04 KBK What's this?
9997663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser        return True
10007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def readline(self):
10027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        save = self.reading
10037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = 1
10055c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.mainloop()  # nested mainloop()
10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        finally:
10077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = save
10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
10095c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
10105c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            line = "\n"
1011bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        if isinstance(line, unicode):
1012bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            import IOBinding
1013bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            try:
1014bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                line = line.encode(IOBinding.encoding)
1015bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            except UnicodeError:
1016bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                pass
10177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
10197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
10205c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            if not use_subprocess:
10215c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser                raise KeyboardInterrupt
10227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.endoffile:
10237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 0
10245c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            line = ""
10257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return line
10267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1028837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
10297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1030003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def cancel_callback(self, event=None):
10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.text.compare("sel.first", "!=", "sel.last"):
10337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return # Active selection -- always use default binding
10347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
10367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.executing or self.reading):
10377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
10387f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.write("KeyboardInterrupt\n")
10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
10407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.endoffile = 0
1042003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        self.canceled = 1
10435c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if (self.executing and self.interp.rpcclt):
104467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.interp.getdebugger():
104567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.restart_subprocess()
104667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            else:
104767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.interrupt_subprocess()
10485c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if self.reading:
10495c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.quit()  # exit the nested mainloop() in readline()
10507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def eof_callback(self, event):
10537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
10547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
10557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.text.compare("iomark", "==", "insert") and
10567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.text.compare("insert", "==", "end-1c")):
10577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
10587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.executing:
10597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
10607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.close()
10617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
10627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
10637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 1
10647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
10657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def home_callback(self, event):
10687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if event.state != 0 and event.keysym == "Home":
10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # <Modifier-Home>; fall back to class binding
10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("iomark", "<=", "insert") and \
10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer           self.text.compare("insert linestart", "<=", "iomark"):
10727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.mark_set("insert", "iomark")
10737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.tag_remove("sel", "1.0", "end")
10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
10757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
10767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def linefeed_callback(self, event):
10787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Insert a linefeed without entering anything (still autoindented)
10797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
10807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
10817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
10827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1083822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
10847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def enter_callback(self, event):
10877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (insert '\n') take over
10897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If some text is selected, recall the selection
10907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (but only if this before the I/O mark)
10917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sel = self.text.get("sel.first", "sel.last")
10937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if sel:
10947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                if self.text.compare("sel.last", "<=", "iomark"):
1095a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                    self.recall(sel, event)
10967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    return "break"
10977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
10997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're strictly before the line containing iomark, recall
11007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # the current line, less a leading prompt, less leading or
11017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # trailing whitespace
11027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "iomark linestart"):
11037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            # Check if there's a relevant stdin range -- if so, use it
11047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            prev = self.text.tag_prevrange("stdin", "insert")
11057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if prev and self.text.compare("insert", "<", prev[1]):
1106a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                self.recall(self.text.get(prev[0], prev[1]), event)
11077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
11087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            next = self.text.tag_nextrange("stdin", "insert")
11097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if next and self.text.compare("insert lineend", ">=", next[0]):
1110a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                self.recall(self.text.get(next[0], next[1]), event)
11117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
11124ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            # No stdin mark -- just get the current line, less any prompt
1113b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            indices = self.text.tag_nextrange("console", "insert linestart")
1114b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            if indices and \
1115b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser               self.text.compare(indices[0], "<=", "insert linestart"):
1116b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser                self.recall(self.text.get(indices[1], "insert lineend"), event)
1117b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            else:
1118b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser                self.recall(self.text.get("insert linestart", "insert lineend"), event)
11197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
1120822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        # If we're between the beginning of the line and the iomark, i.e.
11214ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        # in the prompt area, move to the end of the prompt
1122822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        if self.text.compare("insert", "<", "iomark"):
11234ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.text.mark_set("insert", "iomark")
11247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input and there's only whitespace
11257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # beyond the cursor, erase that whitespace first
11267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        s = self.text.get("insert", "end-1c")
1127837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if s and not s.strip():
11287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.delete("insert", "end-1c")
11297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input before its last line,
11307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # insert a newline right at the insert point
11317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "end-1c linestart"):
1132822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
11347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # We're in the last line; append a newline and submit it
11357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
11367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
11377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
11387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
11397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1140822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.tag_add("stdin", "iomark", "end-1c")
11427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.update_idletasks()
11437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
11447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit() # Break out of recursive mainloop() in raw_input()
11457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
11467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runit()
11477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1149a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser    def recall(self, s, event):
1150cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        # remove leading and trailing empty or whitespace lines
1151cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        s = re.sub(r'^\s*\n', '' , s)
1152cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        s = re.sub(r'\n\s*$', '', s)
1153cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        lines = s.split('\n')
1154a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        self.text.undo_block_start()
1155a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        try:
1156a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.tag_remove("sel", "1.0", "end")
1157a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.mark_set("insert", "end-1c")
1158cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            prefix = self.text.get("insert linestart", "insert")
1159cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            if prefix.rstrip().endswith(':'):
11608fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser                self.newline_and_indent_event(event)
1161cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                prefix = self.text.get("insert linestart", "insert")
1162cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            self.text.insert("insert", lines[0].strip())
11638fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser            if len(lines) > 1:
1164cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
1165cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                new_base_indent  = re.search(r'^([ \t]*)', prefix).group(0)
11668fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser                for line in lines[1:]:
1167cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                    if line.startswith(orig_base_indent):
1168cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                        # replace orig base indentation with new indentation
1169cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                        line = new_base_indent + line[len(orig_base_indent):]
1170cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                    self.text.insert('insert', '\n'+line.rstrip())
1171a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        finally:
1172a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.see("insert")
1173a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.undo_block_stop()
11747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runit(self):
11767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
11777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Strip off last newline and surrounding whitespace.
11787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (To allow you to hit return twice to end a statement.)
11797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        i = len(line)
11807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
11817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
11827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if i > 0 and line[i-1] == "\n":
11837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
11847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
11857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
11867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = line[:i]
11877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        more = self.interp.runsource(line)
11887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_stack_viewer(self, event=None):
11905d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
11915d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return self.interp.remote_stack_viewer()
11927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
11937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.last_traceback
11947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("No stack trace",
11967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "There is no stack trace yet.\n"
11977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "(sys.last_traceback is not defined)",
11987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
11997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
12007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        from StackViewer import StackBrowser
12017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sv = StackBrowser(self.root, self.flist)
12027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12031061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def view_restart_mark(self, event=None):
12041061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("iomark")
12051061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("restart")
12061061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
12071061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def restart_shell(self, event=None):
120867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.interp.restart_subprocess()
12091061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
12107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showprompt(self):
12117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
12127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
12137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = str(sys.ps1)
12147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
12157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = ""
12167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console.write(s)
12177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
12185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
1219dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        self.io.reset_undo()
12207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def resetoutput(self):
12227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        source = self.text.get("iomark", "end-1c")
12237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
12247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.history_store(source)
12257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.get("end-2c") != "\n":
12267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("end-1c", "\n")
12277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("iomark", "end-1c")
12285d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
12297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout.softspace = 0
12307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s, tags=()):
1232003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
1233003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "right")
1234003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            OutputWindow.write(self, s, tags, "iomark")
1235003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "left")
1236003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        except:
1237003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            pass
12387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
12397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
12407f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
12417f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                raise KeyboardInterrupt
12427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1243dcba6622f52efafa28104a07db9d5ba2b1a8d628Kurt B. Kaiserclass PseudoFile(object):
12447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1245bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis    def __init__(self, shell, tags, encoding=None):
12467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell = shell
12477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tags = tags
12485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.softspace = 0
1249bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.encoding = encoding
12507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
12527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell.write(s, self.tags)
12537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def writelines(self, l):
12557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        map(self.write, l)
12567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def flush(self):
12587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass
12597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1261837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
12627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1263969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
12647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\
12657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
126611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle  [-deins] [-t title] [file]*
126711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
126811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] - [arg]*
12696655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
1270f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -h         print this help message and exit
12718f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
1272f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1273f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration:
1274f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1275f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -e         open an edit window
1276f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -i         open a shell window
1277f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1278f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell:
1279f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1280f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -c cmd     run the command in a shell, or
1281f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -r file    run script from file
1282f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1283f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -d         enable the debugger
1284f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1285f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -t title   set title of shell window
1286f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1287f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used.
1288f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1289f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1290f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1291f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples:
12927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1293f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle
1294f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open an edit window or shell depending on IDLE's configuration.
129596d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser
1296f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py
1297f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Edit the files, also open a shell if configured to start with shell.
1298f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1299f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py
1300f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1301f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        window with the title "Baz".
1302f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1303f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo"
1304f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window and run the command, passing "-c" in sys.argv[0]
1305f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foo" in sys.argv[1].
1306f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1307f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World"
1308f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run a startup script, enable the debugger, and
1309f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1310f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv[1].
1311f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1312f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar"
1313f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run the script piped in, passing '' in sys.argv[0]
1314f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foobar" in sys.argv[1].
13157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer"""
13167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1317969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main():
1318f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    global flist, root, use_subprocess
1319f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
13208f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser    use_subprocess = True
1321f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_shell = False
1322f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = False
1323f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    debug = False
1324969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    cmd = None
1325969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    script = None
1326f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    startup = False
1327969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    try:
13288f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
1329969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    except getopt.error, msg:
1330969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write("Error: %s\n" % str(msg))
1331969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write(usage_msg)
1332969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.exit(2)
1333969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for o, a in opts:
1334969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-c':
1335969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            cmd = a
1336f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1337969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-d':
1338f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            debug = True
1339f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1340969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-e':
1341f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_edit = True
1342f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-h':
1343f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.stdout.write(usage_msg)
1344f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.exit()
1345f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-i':
1346f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
13478f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if o == '-n':
13488f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            use_subprocess = False
1349969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-r':
1350969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            script = a
1351f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if os.path.isfile(script):
1352f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                pass
1353f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            else:
1354f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                print "No script file: ", script
1355f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.exit()
1356f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1357969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-s':
1358f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            startup = True
1359f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1360969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-t':
1361969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            PyShell.shell_title = a
1362f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1363f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1364f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        cmd = sys.stdin.read()
1365f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_shell = True
1366f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # process sys.argv and sys.path:
1367969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for i in range(len(sys.path)):
1368969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.path[i] = os.path.abspath(sys.path[i])
1369f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1370f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [''] + args[1:]
1371f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif cmd:
1372f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = ['-c'] + args
1373f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif script:
1374f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [script] + args
1375f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif args:
1376f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_edit = True
1377f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        pathx = []
1378969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        for filename in args:
1379969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            pathx.append(os.path.dirname(filename))
1380f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        for dir in pathx:
1381f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            dir = os.path.abspath(dir)
1382f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not dir in sys.path:
1383f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.path.insert(0, dir)
1384ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser    else:
1385ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        dir = os.getcwd()
1386ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        if not dir in sys.path:
1387ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser            sys.path.insert(0, dir)
1388f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # check the IDLE settings configuration (but command line overrides)
1389f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    edit_start = idleConf.GetOption('main', 'General',
13906655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                                    'editor-on-startup', type='bool')
1391f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = enable_edit or edit_start
13926655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    enable_shell = enable_shell or not edit_start
1393f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # start editor and/or shell windows:
1394969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root = Tk(className="Idle")
139519302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1396969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    fixwordbreaks(root)
1397969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.withdraw()
1398969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    flist = PyShellFileList(root)
139919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren    macosxSupport.setupApp(root, flist)
140019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1401f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if enable_edit:
1402f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if not (cmd or script):
1403f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            for filename in args:
1404f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.open(filename)
1405f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not args:
1406f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.new()
1407af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if enable_shell:
140819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        shell = flist.open_shell()
140919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        if not shell:
1410af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return # couldn't open shell
141119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
141219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        if macosxSupport.runningAsOSXApp() and flist.dict:
141319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            # On OSX: when the user has double-clicked on a file that causes
14144f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters            # IDLE to be launched the shell window will open just in front of
14154f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters            # the file she wants to see. Lower the interpreter window when
141619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            # there are open files.
141719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            shell.top.lower()
141819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1419f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    shell = flist.pyshell
1420f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # handle remaining options:
1421f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if debug:
1422f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.open_debugger()
1423969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    if startup:
1424969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        filename = os.environ.get("IDLESTARTUP") or \
1425969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser                   os.environ.get("PYTHONSTARTUP")
1426969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if filename and os.path.isfile(filename):
1427f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(filename)
1428af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if shell and cmd or script:
1429f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.interp.runcommand("""if 1:
1430f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            import sys as _sys
143170a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            _sys.argv = %r
1432f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            del _sys
143370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            \n""" % (sys.argv,))
1434f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if cmd:
1435f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execsource(cmd)
1436f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        elif script:
143711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            shell.interp.prepend_syspath(script)
1438f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(script)
143919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1440969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.mainloop()
1441969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.destroy()
1442969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
14437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__":
14449e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser    sys.modules['PyShell'] = sys.modules['__main__']
14457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    main()
1446