17aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#! /usr/bin/env python
2bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedyfrom __future__ import print_function
37aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
47aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport os
56e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiserimport os.path
67aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport sys
77aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport string
87aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport getopt
97aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport re
105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport socket
115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport time
12003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiserimport threading
13e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwisimport io
147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport linecache
167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom code import InteractiveInterpreter
174ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedyfrom platform import python_version, system
187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
192303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaisertry:
206634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl    from Tkinter import *
212303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiserexcept ImportError:
22bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy    print("** IDLE can't import Tkinter.\n"
23bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy          "Your Python may not be configured for Tk. **", file=sys.__stderr__)
242303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    sys.exit(1)
256634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandlimport tkMessageBox
267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
27d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.EditorWindow import EditorWindow, fixwordbreaks
28d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.FileList import FileList
29d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.ColorDelegator import ColorDelegator
30d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.UndoDelegator import UndoDelegator
31d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.OutputWindow import OutputWindow
32d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.configHandler import idleConf
33d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import rpc
34d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import Debugger
35d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import RemoteDebugger
36d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import macosxSupport
374b2c468e7464dc29700b50afcfc0bf101bea7fb8Serhiy Storchakafrom idlelib import IOBinding
385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
39b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_"
40013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserHOST = '127.0.0.1' # python execution server on localhost loopback
41013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserPORT = 0  # someday pass in host, port for remote debug capability
42b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser
43a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry:
44a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    from signal import SIGTERM
45a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError:
46a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    SIGTERM = 15
47a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser
4849a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# Override warnings module to write to warning_stream.  Initialize to send IDLE
4949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# internal warnings to the console.  ScriptBinding.check_syntax() will
5049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# temporarily redirect the stream to the shell window to display warnings when
5149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# checking user's code.
528eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedywarning_stream = sys.__stderr__  # None, at least on Windows, if no console.
538eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedyimport warnings
548eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
558eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedydef idle_formatwarning(message, category, filename, lineno, line=None):
568eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    """Format warnings the IDLE way."""
578eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
588eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    s = "\nWarning (from warnings module):\n"
598eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    s += '  File \"%s\", line %s\n' % (filename, lineno)
608eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if line is None:
618eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        line = linecache.getline(filename, lineno)
628eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    line = line.strip()
638eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if line:
648eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        s += "    %s\n" % line
658eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    s += "%s: %s\n" % (category.__name__, message)
668eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    return s
678eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
688eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedydef idle_showwarning(
698eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        message, category, filename, lineno, file=None, line=None):
708eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    """Show Idle-format warning (after replacing warnings.showwarning).
718eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
728eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    The differences are the formatter called, the file=None replacement,
738eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    which can be None, the capture of the consequence AttributeError,
748eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    and the output of a hard-coded prompt.
758eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    """
768eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if file is None:
778eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        file = warning_stream
788eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    try:
798eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        file.write(idle_formatwarning(
808eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy                message, category, filename, lineno, line=line))
818eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        file.write(">>> ")
828eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    except (AttributeError, IOError):
838eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        pass  # if file (probably __stderr__) is invalid, skip warning.
848eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
858eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy_warnings_showwarning = None
868eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
878eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedydef capture_warnings(capture):
888eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    "Replace warning.showwarning with idle_showwarning, or reverse."
898eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
908eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    global _warnings_showwarning
918eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if capture:
928eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        if _warnings_showwarning is None:
938eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            _warnings_showwarning = warnings.showwarning
948eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            warnings.showwarning = idle_showwarning
958eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    else:
968eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        if _warnings_showwarning is not None:
978eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            warnings.showwarning = _warnings_showwarning
988eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            _warnings_showwarning = None
998eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
1008eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedycapture_warnings(True)
1015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
102f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiserdef extended_linecache_checkcache(filename=None,
103f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser                                  orig_checkcache=linecache.checkcache):
10445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """Extend linecache.checkcache to preserve the <pyshell#...> entries
10545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
106f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    Rather than repeating the linecache code, patch it to save the
107f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    <pyshell#...> entries, call the original linecache.checkcache()
108f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo    (skipping them), and then restore the saved entries.
109f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser
110f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    orig_checkcache is bound at definition time to the original
111f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    method, allowing it to be patched.
11245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """
1137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache = linecache.cache
1147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    save = {}
115f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo    for key in list(cache):
116f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo        if key[:1] + key[-1:] == '<>':
117f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo            save[key] = cache.pop(key)
118f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo    orig_checkcache(filename)
1197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache.update(save)
1206655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
121818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache():
122818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache
1237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
1257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow):
126183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    "Regular text edit window in IDLE, supports breakpoints"
12745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
1287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, *args):
12945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.breakpoints = []
130931237e2e66975c54e2ac6c5e503ee2992a22bcfRaymond Hettinger        EditorWindow.__init__(self, *args)
1317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
13245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
1337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
1347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
135bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
136bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                           'breakpoints.lst')
137a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        # whenever a file is changed, restore breakpoints
138bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        def filename_changed_hook(old_hook=self.io.filename_change_hook,
139bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                  self=self):
140a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            self.restore_file_breaks()
141a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            old_hook()
142a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.io.set_filename_change_hook(filename_changed_hook)
143d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy        if self.io.filename:
144d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy            self.restore_file_breaks()
14525327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy        self.color_breakpoint_text()
146a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
1475018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    rmenu_specs = [
1485018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Cut", "<<cut>>", "rmenu_check_cut"),
1495018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Copy", "<<copy>>", "rmenu_check_copy"),
1505018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Paste", "<<paste>>", "rmenu_check_paste"),
1515018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Set Breakpoint", "<<set-breakpoint-here>>", None),
1525018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Clear Breakpoint", "<<clear-breakpoint-here>>", None)
1535018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    ]
1547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
15525327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy    def color_breakpoint_text(self, color=True):
15625327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy        "Turn colorizing of breakpoint text on or off"
15708da46e10f3fb49ecb2d69bc934667e5a352b2a7Terry Jan Reedy        if self.io is None:
15808da46e10f3fb49ecb2d69bc934667e5a352b2a7Terry Jan Reedy            # possible due to update in restore_file_breaks
15908da46e10f3fb49ecb2d69bc934667e5a352b2a7Terry Jan Reedy            return
16025327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy        if color:
16135aa5d07a2865f34d178e7c35c1f1eeb73289eacTerry Jan Reedy            theme = idleConf.CurrentTheme()
16225327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy            cfg = idleConf.GetHighlight(theme, "break")
16325327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy        else:
16425327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy            cfg = {'foreground': '', 'background': ''}
16525327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy        self.text.tag_config('BREAK', cfg)
16625327d4d3bc1bab8b0263a44f8d8790ce03c7877Terry Jan Reedy
167a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint(self, lineno):
16845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
16945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
170a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
17145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
1722848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy            self.breakpoints.index(lineno)
173a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except ValueError:  # only add if missing, i.e. do once
17445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.append(lineno)
17545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:    # update the subprocess debugger
17645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
17745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.set_breakpoint_here(filename, lineno)
17845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except: # but debugger may not be active right now....
17945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
1807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
181a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint_here(self, event=None):
182a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
183a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        filename = self.io.filename
184a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if not filename:
185a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            text.bell()
186a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            return
187a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        lineno = int(float(text.index("insert")))
188a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.set_breakpoint(lineno)
189a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
190669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser    def clear_breakpoint_here(self, event=None):
19145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
19245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
19345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if not filename:
19445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.bell()
195669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser            return
19645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        lineno = int(float(text.index("insert")))
19745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
19845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.remove(lineno)
19945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
20045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
20145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text.tag_remove("BREAK", "insert linestart",\
20245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                        "insert lineend +1char")
20345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
20445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
20545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.clear_breakpoint_here(filename, lineno)
20645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
20745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
20845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
20945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def clear_file_breaks(self):
21045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if self.breakpoints:
21145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text = self.text
21245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            filename = self.io.filename
21345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            if not filename:
21445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                text.bell()
21545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                return
21645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints = []
21745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.tag_remove("BREAK", "1.0", END)
21845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            try:
21945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug = self.flist.pyshell.interp.debugger
22045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug.clear_file_breaks(filename)
22145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            except:
22245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                pass
22345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
224a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def store_file_breaks(self):
225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Save breakpoints when file is saved"
226bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be run.  The breaks are saved at that time.  If we introduce
228bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     a temporary file save feature the save breaks functionality
229bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     needs to be re-verified, since the breaks at the time the
230bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     temp file is created may differ from the breaks at the last
2317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     permanent save of the file.  Currently, a break introduced
2327f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     after a save will be effective, but not persistent.
2337f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     This is necessary to keep the saved breaks synched with the
2347f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     saved file.
235bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #
236987a02b5cfe57c4430f2cd72d20aaa0d513ec7c3Terry Jan Reedy        #     Breakpoints are set as tagged ranges in the text.
237987a02b5cfe57c4430f2cd72d20aaa0d513ec7c3Terry Jan Reedy        #     Since a modified file has to be saved before it is
238bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     run, and since self.breakpoints (from which the subprocess
239bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     debugger is loaded) is updated during the save, the visible
240bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     breaks stay synched with the subprocess even if one of these
241bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     unexpected breakpoint deletions occurs.
242bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
243bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
244a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        try:
24540ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily            with open(self.breakpointPath,"r") as old_file:
24640ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                lines = old_file.readlines()
247a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except IOError:
248bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = []
24940ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily        try:
25040ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily            with open(self.breakpointPath,"w") as new_file:
25140ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                for line in lines:
25240ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    if not line.startswith(filename + '='):
25340ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                        new_file.write(line)
25440ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                self.update_breakpoints()
25540ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                breaks = self.breakpoints
25640ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                if breaks:
25740ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    new_file.write(filename + '=' + str(breaks) + '\n')
25840ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily        except IOError as err:
25940ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily            if not getattr(self.root, "breakpoint_error_displayed", False):
26040ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                self.root.breakpoint_error_displayed = True
26140ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                tkMessageBox.showerror(title='IDLE Error',
26240ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    message='Unable to update breakpoint list:\n%s'
26340ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                        % str(err),
26440ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    parent=self.text)
265a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
266a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def restore_file_breaks(self):
267a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.text.update()   # this enables setting "BREAK" tags to be visible
268d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy        if self.io is None:
269d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy            # can happen if IDLE closes due to the .update() call
270d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy            return
271bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
272bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if filename is None:
273bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            return
27469371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey        if os.path.isfile(self.breakpointPath):
275bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
27669371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey            for line in lines:
277bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                if line.startswith(filename + '='):
2786655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                    breakpoint_linenumbers = eval(line[len(filename)+1:])
27969371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                    for breakpoint_linenumber in breakpoint_linenumbers:
28069371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                        self.set_breakpoint(breakpoint_linenumber)
281a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
282bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def update_breakpoints(self):
283bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Retrieves all the breakpoints in the current window"
284a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
285bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        ranges = text.tag_ranges("BREAK")
286bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        linenumber_list = self.ranges_to_linenumbers(ranges)
287bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpoints = linenumber_list
288bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
289bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def ranges_to_linenumbers(self, ranges):
290bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        lines = []
291bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        for index in range(0, len(ranges), 2):
2928a15c37df7415189f6e9291df074fba68b68df43Andrew Svetlov            lineno = int(float(ranges[index].string))
2938a15c37df7415189f6e9291df074fba68b68df43Andrew Svetlov            end = int(float(ranges[index+1].string))
294bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            while lineno < end:
295bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lines.append(lineno)
296bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lineno += 1
297bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        return lines
298bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
29911220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently
300bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#    def saved_change_hook(self):
301bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        "Extend base method - clear breaks if module is modified"
302bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        if not self.get_saved():
303bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#            self.clear_file_breaks()
304bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        EditorWindow.saved_change_hook(self)
30545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
30645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def _close(self):
30745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        "Extend base method - clear breaks when module is closed"
30845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.clear_file_breaks()
30945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        EditorWindow._close(self)
3106655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
3117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList):
313183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    "Extend base class: IDLE supports a shell and breakpoints"
3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
315183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    # override FileList's class variable, instances return PyShellEditorWindow
316183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    # instead of EditorWindow when new edit windows are created.
3177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    EditorWindow = PyShellEditorWindow
3187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    pyshell = None
3207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_shell(self, event=None):
3227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.pyshell:
323183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            self.pyshell.top.wakeup()
3247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
3257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell = PyShell(self)
326af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if self.pyshell:
327af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                if not self.pyshell.begin():
328af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                    return None
3297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.pyshell
3307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator):
33383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: colorizer for the shell window itself"
3346655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
335b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def __init__(self):
336b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.__init__(self)
337b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.LoadTagDefs()
3387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recolorize_main(self):
3407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_remove("TODO", "1.0", "iomark")
3417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_add("SYNC", "1.0", "iomark")
3427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ColorDelegator.recolorize_main(self)
3436655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
344b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def LoadTagDefs(self):
345b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.LoadTagDefs(self)
34635aa5d07a2865f34d178e7c35c1f1eeb73289eacTerry Jan Reedy        theme = idleConf.CurrentTheme()
347b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.tagdefs.update({
348b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdin": {'background':None,'foreground':None},
349b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdout": idleConf.GetHighlight(theme, "stdout"),
350b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stderr": idleConf.GetHighlight(theme, "stderr"),
351b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "console": idleConf.GetHighlight(theme, "console"),
352b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        })
3537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3545e247b705e3bdd77967bca76601b791003389adaNed Deily    def removecolors(self):
3555e247b705e3bdd77967bca76601b791003389adaNed Deily        # Don't remove shell color tags before "iomark"
3565e247b705e3bdd77967bca76601b791003389adaNed Deily        for tag in self.tagdefs:
3575e247b705e3bdd77967bca76601b791003389adaNed Deily            self.tag_remove(tag, "iomark", "end")
3585e247b705e3bdd77967bca76601b791003389adaNed Deily
3597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator):
36083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: forbid insert/delete before the I/O mark"
3617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def insert(self, index, chars, tags=None):
3637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
3647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index, "<", "iomark"):
3657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
3667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.insert(self, index, chars, tags)
3707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def delete(self, index1, index2=None):
3727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
3737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index1, "<", "iomark"):
3747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
3757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.delete(self, index1, index2)
3797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
38067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
38167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient):
38267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
38367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser    def handle_EOF(self):
38467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        "Override the base class - just re-raise EOFError"
38567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        raise EOFError
38667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
3878d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser
3887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter):
3897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, tkconsole):
3917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole = tkconsole
3927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        locals = sys.modules['__main__'].__dict__
3937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.__init__(self, locals=locals)
39494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = None
3956f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
396013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.subprocess_arglist = None
397013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.port = PORT
39886d669bdb849ab5cf99623494c706a5ab416e84eNed Deily        self.original_compiler_flags = self.compile.compiler.flags
3997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
40016ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy    _afterid = None
4015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcclt = None
4025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcpid = None
4035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4046655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    def spawn_subprocess(self):
405c8a730bf72b1c95651a8a39766bf56635956a2e0Florent Xicluna        if self.subprocess_arglist is None:
406013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            self.subprocess_arglist = self.build_subprocess_arglist()
40762df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        args = self.subprocess_arglist
408b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
40963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser
410f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds    def build_subprocess_arglist(self):
411013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        assert (self.port!=0), (
412013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "Socket should have been assigned a port number.")
4132398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        w = ['-W' + s for s in sys.warnoptions]
414d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl        if 1/2 > 0: # account for new division
415d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl            w.append('-Qnew')
4162398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # Maybe IDLE is installed and is being accessed via sys.path,
4172398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # or maybe it's not installed and the idle.py script is being
4182398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # run from the IDLE source directory.
41962df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
42062df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser                                       default=False, type='bool')
4212398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        if __name__ == 'idlelib.PyShell':
42270a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
423f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds        else:
42470a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            command = "__import__('run').main(%r)" % (del_exitf,)
425b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        if sys.platform[:3] == 'win' and ' ' in sys.executable:
426b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            # handle embedded space in path by quoting the argument
427b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = '"%s"' % sys.executable
428b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        else:
429b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = sys.executable
430b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        return [decorated_exec] + w + ["-c", command, str(self.port)]
431f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds
43263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def start_subprocess(self):
433013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        addr = (HOST, self.port)
434013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        # GUI makes several attempts to acquire socket, listens for connection
4355db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        for i in range(3):
4365d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            time.sleep(i)
4375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            try:
43867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.rpcclt = MyRPCClient(addr)
4395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                break
4402848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy            except socket.error:
441af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                pass
4425d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
443af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_port_binding_error()
444af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
445013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        # if PORT was 0, system will assign an 'ephemeral' port. Find it out:
446013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.port = self.rpcclt.listening_sock.getsockname()[1]
447013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        # if PORT was not 0, probably working with a remote execution server
448013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        if PORT != 0:
449013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # To allow reconnection within the 2MSL wait (cf. Stevens TCP
450013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # V1, 18.6),  set SO_REUSEADDR.  Note that this can be problematic
451013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # on Windows since the implementation allows two active sockets on
452013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # the same address!
453013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET,
454013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser                                           socket.SO_REUSEADDR, 1)
455013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.spawn_subprocess()
456013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        #time.sleep(20) # test to simulate GUI not accepting connection
457b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        # Accept the connection from the Python execution server
458af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        self.rpcclt.listening_sock.settimeout(10)
459af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
460af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
4612848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy        except socket.timeout:
462af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
463af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
4649abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.rpcclt.register("console", self.tkconsole)
4659abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.rpcclt.register("stdin", self.tkconsole.stdin)
466969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdout", self.tkconsole.stdout)
467969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stderr", self.tkconsole.stderr)
4685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcclt.register("flist", self.tkconsole.flist)
4698cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser        self.rpcclt.register("linecache", linecache)
4709f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.rpcclt.register("interp", self)
471b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        self.transfer_path(with_cwd=True)
4725d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.poll_subprocess()
473af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
4745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4758755d78e4fa867202a020624defa4e0e4b56afbbTerry Jan Reedy    def restart_subprocess(self, with_cwd=False, filename=''):
4766f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if self.restarting:
477af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return self.rpcclt
4786f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = True
47963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        # close only the subprocess debugger
48045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        debug = self.getdebugger()
48145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
482003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            try:
4839ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser                # Only close subprocess debugger, don't unregister gui_adap!
484003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
485003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            except:
486003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                pass
487003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # Kill subprocess, spawn a new one, accept connection.
488a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
489a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
4907f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console = self.tkconsole
4916f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        was_executing = console.executing
4927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.executing = False
49363857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.spawn_subprocess()
494af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
495af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
4962848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy        except socket.timeout:
497af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
498af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
499b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        self.transfer_path(with_cwd=with_cwd)
500ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        console.stop_readline()
5011061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        # annotate restart in shell window and mark it
5024cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        console.text.delete("iomark", "end-1c")
503b50d3b2cd322d757852aa783c69127a44906212dTerry Jan Reedy        tag = 'RESTART: ' + (filename if filename else 'Shell')
5048755d78e4fa867202a020624defa4e0e4b56afbbTerry Jan Reedy        halfbar = ((int(console.width) -len(tag) - 4) // 2) * '='
5058755d78e4fa867202a020624defa4e0e4b56afbbTerry Jan Reedy        console.write("\n{0} {1} {0}".format(halfbar, tag))
5061061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_set("restart", "end-1c")
5071061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_gravity("restart", "left")
5088755d78e4fa867202a020624defa4e0e4b56afbbTerry Jan Reedy        if not filename:
5098755d78e4fa867202a020624defa4e0e4b56afbbTerry Jan Reedy            console.showprompt()
510003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # restart subprocess debugger
51145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
5129ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser            # Restarted debugger connects to current instance of debug GUI
5132848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy            RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
51445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            # reload remote debugger breakpoints for all PyShellEditWindows
51545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.load_breakpoints()
51686d669bdb849ab5cf99623494c706a5ab416e84eNed Deily        self.compile.compiler.flags = self.original_compiler_flags
5176f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
518af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
51945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
520003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def __request_interrupt(self):
521a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
522003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
523003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def interrupt_subprocess(self):
524a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        threading.Thread(target=self.__request_interrupt).start()
525003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
526a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def kill_subprocess(self):
52716ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy        if self._afterid is not None:
52816ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy            self.tkconsole.text.after_cancel(self._afterid)
529af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
530af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.close()
531af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except AttributeError:  # no socket
532af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            pass
533a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
534a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.executing = False
535a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt = None
53611c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
537a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def unix_terminate(self):
538a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        "UNIX: make sure subprocess is terminated and collect status"
539a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        if hasattr(os, 'kill'):
540a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            try:
541a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                os.kill(self.rpcpid, SIGTERM)
542a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            except OSError:
543a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                # process already terminated:
544a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                return
545a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            else:
546a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                try:
547a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    os.waitpid(self.rpcpid, 0)
548a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                except OSError:
549a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    return
55011c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
551b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy    def transfer_path(self, with_cwd=False):
552b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        if with_cwd:        # Issue 13506
553b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy            path = ['']     # include Current Working Directory
554b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy            path.extend(sys.path)
555b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        else:
556b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy            path = sys.path
5571d4ae48f48b2da82a89769a714644eb55a541888Terry Jan Reedy
558f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.runcommand("""if 1:
559f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        import sys as _sys
56070a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald        _sys.path = %r
561f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        del _sys
562b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        \n""" % (path,))
563f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
5645d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    active_seq = None
5655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
5665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def poll_subprocess(self):
5675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        clt = self.rpcclt
5685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if clt is None:
5695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
570003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
571a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            response = clt.pollresponse(self.active_seq, wait=0.05)
572a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        except (EOFError, IOError, KeyboardInterrupt):
573a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # lost connection or subprocess terminated itself, restart
574a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # [the KBI is from rpc.SocketIO.handle_EOF()]
57567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.tkconsole.closing:
57667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                return
577003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = None
578003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.restart_subprocess()
5795d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if response:
5805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.resetoutput()
5815d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.active_seq = None
5825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            how, what = response
583bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            console = self.tkconsole.console
5845d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            if how == "OK":
5855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if what is not None:
586bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                    print(repr(what), file=console)
5875d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "EXCEPTION":
5885d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
5895d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                    self.remote_stack_viewer()
5905d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "ERROR":
5910930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
592bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                print(errmsg, what, file=sys.__stderr__)
593bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                print(errmsg, what, file=console)
594bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            # we received a response to the currently active seq number:
595d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser            try:
596d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                self.tkconsole.endexecuting()
597d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser            except AttributeError:  # shell may have closed
598d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                pass
59988957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        # Reschedule myself
60088957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        if not self.tkconsole.closing:
60116ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy            self._afterid = self.tkconsole.text.after(
60216ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy                self.tkconsole.pollinterval, self.poll_subprocess)
6035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
60445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    debugger = None
60545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
60645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def setdebugger(self, debugger):
60745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.debugger = debugger
60845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
60945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def getdebugger(self):
61045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        return self.debugger
61145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
6129f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser    def open_remote_stack_viewer(self):
6139f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """Initiate the remote stack viewer from a separate thread.
6149f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
6159f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        This method is called from the subprocess, and by returning from this
6169f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        method we allow the subprocess to unblock.  After a bit the shell
6179f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        requests the subprocess to open the remote stack viewer which returns a
618c569cfebcebd3d3c8cf77e6c8971a19c78ff7261Ezio Melotti        static object looking at the last exception.  It is queried through
6199f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        the RPC mechanism.
6209f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
6219f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """
6229f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.tkconsole.text.after(300, self.remote_stack_viewer)
6239f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        return
6249f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
6255d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def remote_stack_viewer(self):
626d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib import RemoteObjectBrowser
627a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
6285d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if oid is None:
6295d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.root.bell()
6305d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
6315d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
632d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib.TreeWidget import ScrolledCanvas, TreeNode
6335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        top = Toplevel(self.tkconsole.root)
63435aa5d07a2865f34d178e7c35c1f1eeb73289eacTerry Jan Reedy        theme = idleConf.CurrentTheme()
63573360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        background = idleConf.GetHighlight(theme, 'normal')['background']
63673360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        sc = ScrolledCanvas(top, bg=background, highlightthickness=0)
6375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc.frame.pack(expand=1, fill="both")
6385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node = TreeNode(sc.canvas, None, item)
6395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node.expand()
6405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # XXX Should GC the remote tree when closing the window
6415d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
6427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    gid = 0
6437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execsource(self, source):
64583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Like runsource() but assumes complete exec source"
6467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
6477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.execfile(filename, source)
6487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execfile(self, filename, source=None):
65083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Execute an existing file"
6517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if source is None:
6527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            source = open(filename, "r").read()
6537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
65423120090f5efe2627ecb56384d5f117893d748a5Terry Jan Reedy            code = compile(source, filename, "exec", dont_inherit=True)
6557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except (OverflowError, SyntaxError):
6567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
657bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy            print('*** Error in script or command!\n'
658bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                  'Traceback (most recent call last):',
659bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                  file=self.tkconsole.stderr)
6607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            InteractiveInterpreter.showsyntaxerror(self, filename)
6616e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.showprompt()
6627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runcode(code)
6647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runsource(self, source):
66683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method: Stuff the source in the line cache first"
6677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
6687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.more = 0
66994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = warnings.filters[:]
67094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        warnings.filterwarnings(action="error", category=SyntaxWarning)
6714b2c468e7464dc29700b50afcfc0bf101bea7fb8Serhiy Storchaka        if isinstance(source, unicode) and IOBinding.encoding != 'utf-8':
672837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            try:
6734b2c468e7464dc29700b50afcfc0bf101bea7fb8Serhiy Storchaka                source = '# -*- coding: %s -*-\n%s' % (
6744b2c468e7464dc29700b50afcfc0bf101bea7fb8Serhiy Storchaka                        IOBinding.encoding,
6754b2c468e7464dc29700b50afcfc0bf101bea7fb8Serhiy Storchaka                        source.encode(IOBinding.encoding))
676837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            except UnicodeError:
677837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.tkconsole.resetoutput()
678cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                self.write("Unsupported characters in input\n")
679837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                return
68094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        try:
681935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser            # InteractiveInterpreter.runsource() calls its runcode() method,
682935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser            # which is overridden (see below)
68394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            return InteractiveInterpreter.runsource(self, source, filename)
68494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        finally:
68594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            if self.save_warnings_filters is not None:
68694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                warnings.filters[:] = self.save_warnings_filters
68794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                self.save_warnings_filters = None
6887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def stuffsource(self, source):
69083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Stuff source in the filename cache"
6917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = "<pyshell#%d>" % self.gid
6927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.gid = self.gid + 1
693837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        lines = source.split("\n")
6947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        linecache.cache[filename] = len(source)+1, 0, lines, filename
6957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return filename
6966655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
69711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser    def prepend_syspath(self, filename):
69811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        "Prepend sys.path with file's directory if not already included"
69911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        self.runcommand("""if 1:
70070a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            _filename = %r
70111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            import sys as _sys
70211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            from os.path import dirname as _dirname
70311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _dir = _dirname(_filename)
70411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            if not _dir in _sys.path:
70511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser                _sys.path.insert(0, _dir)
70611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            del _filename, _sys, _dirname, _dir
70770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            \n""" % (filename,))
70811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser
7097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showsyntaxerror(self, filename=None):
71083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """Extend base class method: Add Colorizing
71183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
71283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        Color the offending position instead of printing it and pointing at it
71383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        with a caret.
71483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
71583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """
7167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.tkconsole.text
7177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        stuff = self.unpackerror()
7186e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        if stuff:
7196e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            msg, lineno, offset, line = stuff
7206e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if lineno == 1:
7216e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark + %d chars" % (offset-1)
7226e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            else:
7236e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark linestart + %d lines + %d chars" % \
7246e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                      (lineno-1, offset-1)
7256e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.tag_add("ERROR", pos)
7266e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.see(pos)
7276e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            char = text.get(pos)
7286e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if char and char in IDENTCHARS:
7296e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                text.tag_add("ERROR", pos + " wordstart", pos)
7307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
7316e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.write("SyntaxError: %s\n" % str(msg))
7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
7336e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.resetoutput()
7346e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            InteractiveInterpreter.showsyntaxerror(self, filename)
7356e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        self.tkconsole.showprompt()
7367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def unpackerror(self):
7387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        type, value, tb = sys.exc_info()
7397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ok = type is SyntaxError
7407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
7417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
7427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                msg, (dummy_filename, lineno, offset, line) = value
743bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                if not offset:
744bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                    offset = 0
7457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except:
7467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                ok = 0
7477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
7487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return msg, lineno, offset, line
7497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
7507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
7517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showtraceback(self):
75383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method to reset output properly"
7547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole.resetoutput()
7557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.checklinecache()
7567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.showtraceback(self)
7575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
7585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.open_stack_viewer()
7597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def checklinecache(self):
7617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        c = linecache.cache
7627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for key in c.keys():
7637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key[:1] + key[-1:] != "<>":
7647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del c[key]
7657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def runcommand(self, code):
76783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Run the code without invoking the debugger"
7685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # The code better not raise an exception!
7695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
770f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz            self.display_executing_dialog()
7715d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return 0
7725d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.rpcclt:
773a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
7745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
7755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            exec code in self.locals
7765d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        return 1
7775d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
7787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runcode(self, code):
77983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
7805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
781003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.restart_subprocess()
7825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.checklinecache()
78394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        if self.save_warnings_filters is not None:
78494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            warnings.filters[:] = self.save_warnings_filters
78594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            self.save_warnings_filters = None
7867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        debugger = self.debugger
7877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
7887f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.tkconsole.beginexecuting()
789dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if not debugger and self.rpcclt is not None:
790dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
791dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                                                        (code,), {})
792dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            elif debugger:
793dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                debugger.run(code, self.locals)
794dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
795dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                exec code in self.locals
796dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser        except SystemExit:
797dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if not self.tkconsole.closing:
798dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                if tkMessageBox.askyesno(
799dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    "Exit?",
800dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    "Do you want to exit altogether?",
801dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    default="yes",
8028bfacc798559bb99bc9e13060b9ff23234760c1fTerry Jan Reedy                    parent=self.tkconsole.text):
803f137e1df2c02f5782c5b0f18a2b3b649f255f63aKurt B. Kaiser                    raise
804dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                else:
805dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.showtraceback()
806dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
807dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                raise
808dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser        except:
809dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if use_subprocess:
810bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                print("IDLE internal error in runcode()",
811bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                      file=self.tkconsole.stderr)
8127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.showtraceback()
813dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                self.tkconsole.endexecuting()
814dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
815dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                if self.tkconsole.canceled:
816dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.tkconsole.canceled = False
817bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                    print("KeyboardInterrupt", file=self.tkconsole.stderr)
818dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                else:
819dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.showtraceback()
8207f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        finally:
8217f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
822d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                try:
823d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                    self.tkconsole.endexecuting()
824d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                except AttributeError:  # shell may have closed
825d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                    pass
8267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
82883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
8297f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.tkconsole.stderr.write(s)
8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
831af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_port_binding_error(self):
832af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
833af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Port Binding Error",
834013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "IDLE can't bind to a TCP/IP port, which is necessary to "
835013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "communicate with its Python execution server.  This might be "
836013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "because no networking is installed on this computer.  "
837013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "Run IDLE with the -n command line switch to start without a "
838013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "subprocess and refer to Help/IDLE Help 'Running without a "
839013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "subprocess' for further details.",
8408bfacc798559bb99bc9e13060b9ff23234760c1fTerry Jan Reedy            parent=self.tkconsole.text)
841af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
842af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_no_subprocess_error(self):
843af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
844af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Subprocess Startup Error",
845af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "IDLE's subprocess didn't make connection.  Either IDLE can't "
846af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "start a subprocess or personal firewall software is blocking "
847af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "the connection.",
8488bfacc798559bb99bc9e13060b9ff23234760c1fTerry Jan Reedy            parent=self.tkconsole.text)
849af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
850af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_executing_dialog(self):
851af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
852af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Already executing",
853af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "The Python Shell window is already executing a command; "
854af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "please wait until it is finished.",
8558bfacc798559bb99bc9e13060b9ff23234760c1fTerry Jan Reedy            parent=self.tkconsole.text)
856af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
857af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
8587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow):
8597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
860d676a3a221b99e1b352e18be0939158dfc37ef82Terry Jan Reedy    shell_title = "Python " + python_version() + " Shell"
8617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # Override classes
8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    ColorDelegator = ModifiedColorDelegator
8647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    UndoDelegator = ModifiedUndoDelegator
8657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
866f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # Override menus
867dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    menu_specs = [
868dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("file", "_File"),
869dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("edit", "_Edit"),
8704cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        ("debug", "_Debug"),
8711061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        ("options", "_Options"),
872b5daa3d6db429017dea1e4f15b78557e03b5f847Ned Deily        ("windows", "_Window"),
873dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("help", "_Help"),
874dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    ]
8757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
87619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # New classes
878d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna    from idlelib.IdleHistory import History
8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, flist=None):
8818f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
88267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            ms = self.menu_specs
88367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if ms[2][0] != "shell":
8847ae354846fff616746eeba6d27ccd5c175591caeKurt B. Kaiser                ms.insert(2, ("shell", "She_ll"))
8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = ModifiedInterpreter(self)
8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if flist is None:
8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root = Tk()
8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            fixwordbreaks(root)
8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root.withdraw()
8907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist = PyShellFileList(root)
8915afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        OutputWindow.__init__(self, flist, None, None)
8935afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8946af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
8956af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.usetabs = True
8966af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        # indentwidth must be 8 when using tabs.  See note in EditorWindow:
8976af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.indentwidth = 8
8986af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.context_use_ps1 = True
8995afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.text
9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.configure(wrap="char")
9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<newline-and-indent>>", self.enter_callback)
9037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<interrupt-execution>>", self.cancel_callback)
9057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<end-of-file>>", self.eof_callback)
9067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
90757bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser        text.bind("<<toggle-debugger>>", self.toggle_debugger)
9087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
9098f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
9108f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<view-restart>>", self.view_restart_mark)
9118f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<restart-shell>>", self.restart_shell)
9125afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
9137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdout = sys.stdout
9147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stderr = sys.stderr
9157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdin = sys.stdin
916d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib import IOBinding
9179abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding)
9189abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding)
9199abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding)
9209abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.console = PseudoOutputFile(self, "console", IOBinding.encoding)
9215d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if not use_subprocess:
9225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdout = self.stdout
9235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stderr = self.stderr
924e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis            sys.stdin = self.stdin
9255afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
9267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = self.History(self.text)
9275afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
92888957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        self.pollinterval = 50  # millisec
9295d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
9304d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser    def get_standard_extension_names(self):
9314d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser        return idleConf.GetExtensions(shell_only=True)
9324d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser
933003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    reading = False
934003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    executing = False
935003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    canceled = False
936003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    endoffile = False
937003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    closing = False
938ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy    _stop_readline_flag = False
9397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
94049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def set_warning_stream(self, stream):
941d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro        global warning_stream
942d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro        warning_stream = stream
94349a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser
94449a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def get_warning_stream(self):
94549a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        return warning_stream
94649a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser
9477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def toggle_debugger(self, event=None):
9487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
9497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("Don't debug now",
9507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "You can only toggle the debugger when idle",
9518bfacc798559bb99bc9e13060b9ff23234760c1fTerry Jan Reedy                parent=self.text)
9527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.set_debugger_indicator()
9537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
9557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db = self.interp.getdebugger()
9567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if db:
9577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.close_debugger()
9587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
9597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.open_debugger()
9607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def set_debugger_indicator(self):
9627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
9637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.setvar("<<toggle-debugger>>", not not db)
9647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9651061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def toggle_jit_stack_viewer(self, event=None):
9667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass # All we need is the variable
9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close_debugger(self):
9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if db:
9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.interp.setdebugger(None)
9727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db.close()
973ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser            if self.interp.rpcclt:
974ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.console.write("[DEBUG OFF]\n")
9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.ps1 = ">>> "
9787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
9797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.set_debugger_indicator()
9807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_debugger(self):
9825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
9837f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
9847f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                           self)
9857f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
9867f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = Debugger.Debugger(self)
9877f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.interp.setdebugger(dbg_gui)
9887f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        dbg_gui.load_breakpoints()
9895d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sys.ps1 = "[DEBUG ON]\n>>> "
9905d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
9915d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_debugger_indicator()
9925d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
9937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def beginexecuting(self):
994ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser        "Helper for ModifiedInterpreter"
9957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
9967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 1
9977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def endexecuting(self):
99983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Helper for ModifiedInterpreter"
10007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 0
10017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.canceled = 0
10025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
10037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close(self):
100583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow.close()"
10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
1007003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = tkMessageBox.askokcancel(
10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Kill?",
1009815ab140302a2f7a541d1bbda650875bd47f8ea2Terry Jan Reedy                "Your program is still running!\n Do you want to kill it?",
10107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                default="ok",
10117f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                parent=self.text)
10125b63acd31e0e40c1a9a9e9762905b0054ff37994Benjamin Peterson            if response is False:
10137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "cancel"
1014ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        self.stop_readline()
10155c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        self.canceled = True
101667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.closing = True
101788957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        return EditorWindow.close(self)
10187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def _close(self):
102083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow._close(), shut down debugger and execution server"
10217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.close_debugger()
10227f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
10237f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.kill_subprocess()
10247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Restore std streams
10257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout = self.save_stdout
10267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stderr = self.save_stderr
10277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdin = self.save_stdin
10287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Break cycles
10297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = None
10307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = None
10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.flist.pyshell = None
10327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = None
103383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        EditorWindow._close(self)
10347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def ispythonsource(self, filename):
103683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override EditorWindow method: never remove the colorizer"
1037837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
10387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def short_title(self):
10407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.shell_title
10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
104294bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser    COPYRIGHT = \
10438f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser          'Type "copyright", "credits" or "license()" for more information.'
104494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser
10457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def begin(self):
10467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10477f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
10487f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = ''
1049af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            client = self.interp.start_subprocess()
1050af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if not client:
1051af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                self.close()
10527663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser                return False
10537f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
10547f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = "==== No Subprocess ===="
1055bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger        self.write("Python %s on %s\n%s\n%s" %
1056bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger                   (sys.version, sys.platform, self.COPYRIGHT, nosub))
1057baf9ef960c22d9bea2d0189549514c0044e68978Terry Jan Reedy        self.text.focus_force()
10587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.showprompt()
10596634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl        import Tkinter
10606634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl        Tkinter._default_root = None # 03Jan04 KBK What's this?
10617663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser        return True
10627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1063ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy    def stop_readline(self):
1064ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        if not self.reading:  # no nested mainloop to exit.
1065ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy            return
1066ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        self._stop_readline_flag = True
1067ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        self.top.quit()
1068ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy
10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def readline(self):
10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        save = self.reading
10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = 1
10735c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.mainloop()  # nested mainloop()
10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        finally:
10757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = save
1076ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        if self._stop_readline_flag:
1077ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy            self._stop_readline_flag = False
1078ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy            return ""
10797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
10805c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
10815c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            line = "\n"
1082bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        if isinstance(line, unicode):
1083d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna            from idlelib import IOBinding
1084bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            try:
1085bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                line = line.encode(IOBinding.encoding)
1086bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            except UnicodeError:
1087bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                pass
10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
10907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
10915c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            if not use_subprocess:
10925c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser                raise KeyboardInterrupt
10937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.endoffile:
10947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 0
10955c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            line = ""
10967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return line
10977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1099837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
11007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1101003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def cancel_callback(self, event=None):
11027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
11037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.text.compare("sel.first", "!=", "sel.last"):
11047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return # Active selection -- always use default binding
11057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
11077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.executing or self.reading):
11087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
11097f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.write("KeyboardInterrupt\n")
11107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
11117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
11127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.endoffile = 0
1113003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        self.canceled = 1
11145c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if (self.executing and self.interp.rpcclt):
111567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.interp.getdebugger():
111667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.restart_subprocess()
111767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            else:
111867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.interrupt_subprocess()
11195c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if self.reading:
11205c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.quit()  # exit the nested mainloop() in readline()
11217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def eof_callback(self, event):
11247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
11257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
11267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.text.compare("iomark", "==", "insert") and
11277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.text.compare("insert", "==", "end-1c")):
11287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
11297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.executing:
11307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
11317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.close()
11327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
11337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
11347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 1
11357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
11367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def linefeed_callback(self, event):
11397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Insert a linefeed without entering anything (still autoindented)
11407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
11417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
11427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
11437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1144822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def enter_callback(self, event):
11487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
11497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (insert '\n') take over
11507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If some text is selected, recall the selection
11517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (but only if this before the I/O mark)
11527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
11537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sel = self.text.get("sel.first", "sel.last")
11547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if sel:
11557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                if self.text.compare("sel.last", "<=", "iomark"):
1156a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                    self.recall(sel, event)
11577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    return "break"
11587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
11607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're strictly before the line containing iomark, recall
11617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # the current line, less a leading prompt, less leading or
11627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # trailing whitespace
11637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "iomark linestart"):
11647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            # Check if there's a relevant stdin range -- if so, use it
11657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            prev = self.text.tag_prevrange("stdin", "insert")
11667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if prev and self.text.compare("insert", "<", prev[1]):
1167a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                self.recall(self.text.get(prev[0], prev[1]), event)
11687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
11697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            next = self.text.tag_nextrange("stdin", "insert")
11707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if next and self.text.compare("insert lineend", ">=", next[0]):
1171a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                self.recall(self.text.get(next[0], next[1]), event)
11727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
11734ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            # No stdin mark -- just get the current line, less any prompt
1174b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            indices = self.text.tag_nextrange("console", "insert linestart")
1175b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            if indices and \
1176b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser               self.text.compare(indices[0], "<=", "insert linestart"):
1177b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser                self.recall(self.text.get(indices[1], "insert lineend"), event)
1178b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            else:
1179b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser                self.recall(self.text.get("insert linestart", "insert lineend"), event)
11807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
1181822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        # If we're between the beginning of the line and the iomark, i.e.
11824ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        # in the prompt area, move to the end of the prompt
1183822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        if self.text.compare("insert", "<", "iomark"):
11844ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.text.mark_set("insert", "iomark")
11857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input and there's only whitespace
11867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # beyond the cursor, erase that whitespace first
11877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        s = self.text.get("insert", "end-1c")
1188837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if s and not s.strip():
11897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.delete("insert", "end-1c")
11907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input before its last line,
11917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # insert a newline right at the insert point
11927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "end-1c linestart"):
1193822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
11957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # We're in the last line; append a newline and submit it
11967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
11977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
11987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
11997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
12007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1201822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
12027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.tag_add("stdin", "iomark", "end-1c")
12037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.update_idletasks()
12047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
12057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit() # Break out of recursive mainloop() in raw_input()
12067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
12077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runit()
12087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
12097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1210a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser    def recall(self, s, event):
1211cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        # remove leading and trailing empty or whitespace lines
1212cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        s = re.sub(r'^\s*\n', '' , s)
1213cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        s = re.sub(r'\n\s*$', '', s)
1214cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        lines = s.split('\n')
1215a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        self.text.undo_block_start()
1216a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        try:
1217a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.tag_remove("sel", "1.0", "end")
1218a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.mark_set("insert", "end-1c")
1219cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            prefix = self.text.get("insert linestart", "insert")
1220cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            if prefix.rstrip().endswith(':'):
12218fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser                self.newline_and_indent_event(event)
1222cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                prefix = self.text.get("insert linestart", "insert")
1223cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            self.text.insert("insert", lines[0].strip())
12248fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser            if len(lines) > 1:
1225cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
1226cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                new_base_indent  = re.search(r'^([ \t]*)', prefix).group(0)
12278fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser                for line in lines[1:]:
1228cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                    if line.startswith(orig_base_indent):
1229cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                        # replace orig base indentation with new indentation
1230cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                        line = new_base_indent + line[len(orig_base_indent):]
1231cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                    self.text.insert('insert', '\n'+line.rstrip())
1232a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        finally:
1233a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.see("insert")
1234a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.undo_block_stop()
12357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runit(self):
12377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
12387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Strip off last newline and surrounding whitespace.
12397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (To allow you to hit return twice to end a statement.)
12407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        i = len(line)
12417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
12427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
12437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if i > 0 and line[i-1] == "\n":
12447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
12457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
12467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
12477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = line[:i]
12482848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy        self.interp.runsource(line)
12497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_stack_viewer(self, event=None):
12515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
12525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return self.interp.remote_stack_viewer()
12537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
12547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.last_traceback
12557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
12567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("No stack trace",
12577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "There is no stack trace yet.\n"
12587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "(sys.last_traceback is not defined)",
12598bfacc798559bb99bc9e13060b9ff23234760c1fTerry Jan Reedy                parent=self.text)
12607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
1261d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib.StackViewer import StackBrowser
12622848925ed252769d5fcc4ee1ba91a250810b1b55Terry Jan Reedy        StackBrowser(self.root, self.flist)
12637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12641061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def view_restart_mark(self, event=None):
12651061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("iomark")
12661061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("restart")
12671061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
12681061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def restart_shell(self, event=None):
1269b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        "Callback for Run/Restart Shell Cntl-F6"
1270b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        self.interp.restart_subprocess(with_cwd=True)
12711061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
12727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showprompt(self):
12737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
12747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
12757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = str(sys.ps1)
12767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
12777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = ""
12787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console.write(s)
12797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
12805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
1281dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        self.io.reset_undo()
12827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def resetoutput(self):
12847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        source = self.text.get("iomark", "end-1c")
12857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
1286b638a38dc07dcc87c62eac5177b96824e2e8dfa2Terry Jan Reedy            self.history.store(source)
12877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.get("end-2c") != "\n":
12887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("end-1c", "\n")
12897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("iomark", "end-1c")
12905d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
12917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout.softspace = 0
12927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s, tags=()):
1294003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
1295003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "right")
1296003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            OutputWindow.write(self, s, tags, "iomark")
1297003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "left")
1298003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        except:
1299003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            pass
13007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
13017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
13027f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
13037f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                raise KeyboardInterrupt
13047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13055018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    def rmenu_check_cut(self):
13065018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        try:
13075018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov            if self.text.compare('sel.first', '<', 'iomark'):
13085018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov                return 'disabled'
13095018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        except TclError: # no selection, so the index 'sel.first' doesn't exist
13105018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov            return 'disabled'
13115018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        return super(PyShell, self).rmenu_check_cut()
13125018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov
13135018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    def rmenu_check_paste(self):
13145018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        if self.text.compare('insert', '<', 'iomark'):
13155018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov            return 'disabled'
13165018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        return super(PyShell, self).rmenu_check_paste()
13175018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov
13189abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoFile(io.TextIOBase):
13197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1320bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis    def __init__(self, shell, tags, encoding=None):
13217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell = shell
13227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tags = tags
13235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.softspace = 0
13249abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._encoding = encoding
13259abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13269abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    @property
13279abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def encoding(self):
13289abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return self._encoding
13299abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13309abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    @property
13319abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def name(self):
13329abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return '<%s>' % self.tags
13339abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13349abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def isatty(self):
13359abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return True
13369abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13379abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13389abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoOutputFile(PseudoFile):
13399abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13409abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def writable(self):
13419abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return True
13427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
13449abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if self.closed:
13459abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise ValueError("write to closed file")
13467057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka        if type(s) not in (unicode, str, bytearray):
13477057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka            # See issue #19481
13487057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka            if isinstance(s, unicode):
1349ac5164dd985397e5bbf89c2789738601b7a47a72Serhiy Storchaka                s = unicode.__getitem__(s, slice(None))
13507057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka            elif isinstance(s, str):
13517057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka                s = str.__str__(s)
13527057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka            elif isinstance(s, bytearray):
13537057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka                s = bytearray.__str__(s)
13547057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka            else:
13557057f3fa4db3df28148c6b764e92789b07271689Serhiy Storchaka                raise TypeError('must be string, not ' + type(s).__name__)
13569abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return self.shell.write(s, self.tags)
13577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13599abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoInputFile(PseudoFile):
13607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13619abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def __init__(self, shell, tags, encoding=None):
13629abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        PseudoFile.__init__(self, shell, tags, encoding)
13639abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._line_buffer = ''
13647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13659abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def readable(self):
13669abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return True
1367e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis
13689abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def read(self, size=-1):
13699abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if self.closed:
13709abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise ValueError("read from closed file")
13719abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size is None:
13729abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            size = -1
13739abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        elif not isinstance(size, int):
13749abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise TypeError('must be int, not ' + type(size).__name__)
13759abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        result = self._line_buffer
13769abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._line_buffer = ''
13779abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size < 0:
13789abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            while True:
13799abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                line = self.shell.readline()
13809abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                if not line: break
13819abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                result += line
13829abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        else:
13839abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            while len(result) < size:
13849abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                line = self.shell.readline()
13859abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                if not line: break
13869abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                result += line
13879abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            self._line_buffer = result[size:]
13889abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            result = result[:size]
13899abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return result
13909abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13919abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def readline(self, size=-1):
13929abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if self.closed:
13939abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise ValueError("read from closed file")
13949abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size is None:
13959abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            size = -1
13969abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        elif not isinstance(size, int):
13979abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise TypeError('must be int, not ' + type(size).__name__)
13989abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        line = self._line_buffer or self.shell.readline()
13999abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size < 0:
14009abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            size = len(line)
14010b6b335253949df26c369ecce35199e9dc2b86f5Serhiy Storchaka        eol = line.find('\n', 0, size)
14020b6b335253949df26c369ecce35199e9dc2b86f5Serhiy Storchaka        if eol >= 0:
14030b6b335253949df26c369ecce35199e9dc2b86f5Serhiy Storchaka            size = eol + 1
14049abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._line_buffer = line[size:]
14059abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return line[:size]
1406e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis
140753dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy    def close(self):
140853dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy        self.shell.close()
140953dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy
1410969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
14113b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedydef fix_x11_paste(root):
14123b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy    "Make paste replace selection on x11.  See issue #5124."
14133b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy    if root._windowingsystem == 'x11':
14143b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy        for cls in 'Text', 'Entry', 'Spinbox':
14153b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy            root.bind_class(
14163b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy                cls,
14173b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy                '<<Paste>>',
14183b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy                'catch {%W delete sel.first sel.last}\n' +
14193b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy                        root.bind_class(cls, '<<Paste>>'))
14203b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy
14213b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy
14227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\
14237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
142411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle  [-deins] [-t title] [file]*
142511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
142611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] - [arg]*
14276655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
1428f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -h         print this help message and exit
14298f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
1430f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1431f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration:
1432f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1433f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -e         open an edit window
1434f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -i         open a shell window
1435f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1436f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell:
1437f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1438f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -c cmd     run the command in a shell, or
1439f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -r file    run script from file
1440f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1441f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -d         enable the debugger
1442f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1443f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -t title   set title of shell window
1444f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1445f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used.
1446f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1447f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1448f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1449f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples:
14507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1451f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle
1452f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open an edit window or shell depending on IDLE's configuration.
145396d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser
1454f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py
1455f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Edit the files, also open a shell if configured to start with shell.
1456f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1457f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py
1458f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1459f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        window with the title "Baz".
1460f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1461f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo"
1462f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window and run the command, passing "-c" in sys.argv[0]
1463f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foo" in sys.argv[1].
1464f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1465f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World"
1466f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run a startup script, enable the debugger, and
1467f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1468f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv[1].
1469f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1470f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar"
1471f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run the script piped in, passing '' in sys.argv[0]
1472f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foobar" in sys.argv[1].
14737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer"""
14747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1475969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main():
1476f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    global flist, root, use_subprocess
1477f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
14788eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    capture_warnings(True)
14798f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser    use_subprocess = True
148034d0c66ef2bcfae00beb9f2b14e393cd00f499e4Roger Serwy    enable_shell = False
1481f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = False
1482f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    debug = False
1483969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    cmd = None
1484969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    script = None
1485f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    startup = False
1486969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    try:
14878f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
14882b149860a052606500cc4293db29cde5c85bf288Terry Jan Reedy    except getopt.error as msg:
1489bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy        print("Error: %s\n%s" % (msg, usage_msg), file=sys.stderr)
1490969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.exit(2)
1491969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for o, a in opts:
1492969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-c':
1493969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            cmd = a
1494f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1495969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-d':
1496f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            debug = True
1497f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1498969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-e':
1499f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_edit = True
1500f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-h':
1501f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.stdout.write(usage_msg)
1502f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.exit()
1503f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-i':
1504f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
15058f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if o == '-n':
15068f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            use_subprocess = False
1507969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-r':
1508969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            script = a
1509f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if os.path.isfile(script):
1510f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                pass
1511f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            else:
1512bee003cf539c79ae4a047f47ce4ea7dc377763e5Terry Jan Reedy                print("No script file: ", script, file=sys.stderr)
1513f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.exit()
1514f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1515969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-s':
1516f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            startup = True
1517f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1518969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-t':
1519969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            PyShell.shell_title = a
1520f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1521f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1522f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        cmd = sys.stdin.read()
1523f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_shell = True
1524f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # process sys.argv and sys.path:
1525969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for i in range(len(sys.path)):
1526969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.path[i] = os.path.abspath(sys.path[i])
1527f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1528f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [''] + args[1:]
1529f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif cmd:
1530f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = ['-c'] + args
1531f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif script:
1532f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [script] + args
1533f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif args:
1534f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_edit = True
1535f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        pathx = []
1536969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        for filename in args:
1537969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            pathx.append(os.path.dirname(filename))
1538f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        for dir in pathx:
1539f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            dir = os.path.abspath(dir)
1540d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna            if dir not in sys.path:
1541f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.path.insert(0, dir)
1542ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser    else:
1543ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        dir = os.getcwd()
1544ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        if not dir in sys.path:
1545ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser            sys.path.insert(0, dir)
1546f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # check the IDLE settings configuration (but command line overrides)
1547f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    edit_start = idleConf.GetOption('main', 'General',
15486655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                                    'editor-on-startup', type='bool')
1549f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = enable_edit or edit_start
155034d0c66ef2bcfae00beb9f2b14e393cd00f499e4Roger Serwy    enable_shell = enable_shell or not enable_edit
15513b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy
1552f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # start editor and/or shell windows:
1553969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root = Tk(className="Idle")
15543b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy    root.withdraw()
155519302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
15564ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy    # set application icon
15574ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy    icondir = os.path.join(os.path.dirname(__file__), 'Icons')
15584ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy    if system() == 'Windows':
15594ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy        iconfile = os.path.join(icondir, 'idle.ico')
15604ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy        root.wm_iconbitmap(default=iconfile)
15614ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy    elif TkVersion >= 8.5:
15624ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy        ext = '.png' if TkVersion >= 8.6 else '.gif'
15634ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy        iconfiles = [os.path.join(icondir, 'idle_%d%s' % (size, ext))
15644ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy                     for size in (16, 32, 48)]
15654ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy        icons = [PhotoImage(file=iconfile) for iconfile in iconfiles]
15664ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy        root.tk.call('wm', 'iconphoto', str(root), "-default", *icons)
15674ade2d25fc585876540ac9d591a44469fd853462Terry Jan Reedy
1568969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    fixwordbreaks(root)
15693b6a53256b18d141f0dda35724cf437282f7e0caTerry Jan Reedy    fix_x11_paste(root)
1570969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    flist = PyShellFileList(root)
157119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren    macosxSupport.setupApp(root, flist)
1572b60d103de7da17a9bc9ded35d84ffe0dc90c1c3eTerry Jan Reedy
1573ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy    if macosxSupport.isAquaTk():
1574ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy        # There are some screwed up <2> class bindings for text
1575ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy        # widgets defined in Tk which we need to do away with.
1576ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy        # See issue #24801.
1577ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy        root.unbind_class('Text', '<B2>')
1578ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy        root.unbind_class('Text', '<B2-Motion>')
1579ca33d56f005589967d5b3d77aa807270d5c376edTerry Jan Reedy        root.unbind_class('Text', '<<PasteSelection>>')
158019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1581f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if enable_edit:
1582f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if not (cmd or script):
15837c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov            for filename in args[:]:
15847c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov                if flist.open(filename) is None:
15857c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov                    # filename is a directory actually, disconsider it
15867c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov                    args.remove(filename)
1587f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not args:
1588f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.new()
1589278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily
1590af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if enable_shell:
159119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        shell = flist.open_shell()
159219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        if not shell:
1593af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return # couldn't open shell
159457847df4e59015c141e645b47112829cf41b582aNed Deily        if macosxSupport.isAquaTk() and flist.dict:
159519302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            # On OSX: when the user has double-clicked on a file that causes
15964f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters            # IDLE to be launched the shell window will open just in front of
15974f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters            # the file she wants to see. Lower the interpreter window when
159819302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            # there are open files.
159919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            shell.top.lower()
1600278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily    else:
1601278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        shell = flist.pyshell
160219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1603278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily    # Handle remaining options. If any of these are set, enable_shell
1604278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily    # was set also, so shell must be true to reach here.
1605f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if debug:
1606f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.open_debugger()
1607969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    if startup:
1608969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        filename = os.environ.get("IDLESTARTUP") or \
1609969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser                   os.environ.get("PYTHONSTARTUP")
1610969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if filename and os.path.isfile(filename):
1611f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(filename)
1612278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily    if cmd or script:
1613f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.interp.runcommand("""if 1:
1614f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            import sys as _sys
161570a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            _sys.argv = %r
1616f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            del _sys
161770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            \n""" % (sys.argv,))
1618f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if cmd:
1619f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execsource(cmd)
1620f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        elif script:
162111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            shell.interp.prepend_syspath(script)
1622f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(script)
1623278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily    elif shell:
1624278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        # If there is a shell window and no cmd or script in progress,
1625278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        # check for problematic OS X Tk versions and print a warning
1626278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        # message in the IDLE shell window; this is less intrusive
1627278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        # than always opening a separate window.
1628278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        tkversionwarning = macosxSupport.tkVersionWarning(root)
1629278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily        if tkversionwarning:
1630278543d5392967fb4bfe2d3b3f71c2281500c458Ned Deily            shell.interp.runcommand("print('%s')" % tkversionwarning)
16312a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily
1632eaa7e7825e9f4b211bc104cfde6cc951f9dcb94eTerry Jan Reedy    while flist.inversedict:  # keep IDLE running while files are open.
1633eaa7e7825e9f4b211bc104cfde6cc951f9dcb94eTerry Jan Reedy        root.mainloop()
1634969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.destroy()
16358eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    capture_warnings(False)
1636969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
16377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__":
16389e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser    sys.modules['PyShell'] = sys.modules['__main__']
16397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    main()
16408eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
16418eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedycapture_warnings(False)  # Make sure turned off; see issue 18081
1642