[Python-checkins] r65300 - in sandbox/trunk/ttk-gsoc/src/idlelib: PyShell.py run.py

guilherme.polo python-checkins at python.org
Wed Jul 30 14:34:21 CEST 2008


Author: guilherme.polo
Date: Wed Jul 30 14:34:19 2008
New Revision: 65300

Log:
Updated idle_showwarning to python 2.6 format. Removed more dependencies on self.text

Modified:
   sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py
   sandbox/trunk/ttk-gsoc/src/idlelib/run.py

Modified: sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py	(original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py	Wed Jul 30 14:34:19 2008
@@ -63,24 +63,31 @@
 except ImportError:
     pass
 else:
-    def idle_showwarning(message, category, filename, lineno):
+    def idle_showwarning(message, category, filename, lineno, line=None):
         file = warning_stream
         try:
-            file.write(warnings.formatwarning(message, category, filename, lineno))
+            file.write(warnings.formatwarning(message, category, filename,
+                lineno, line))
         except IOError:
             pass  ## file (probably __stderr__) is invalid, warning dropped.
     warnings.showwarning = idle_showwarning
-    def idle_formatwarning(message, category, filename, lineno):
+    def idle_formatwarning(message, category, filename, lineno, line=None):
         """Format warnings the IDLE way"""
         s = "\nWarning (from warnings module):\n"
         s += '  File \"%s\", line %s\n' % (filename, lineno)
-        line = linecache.getline(filename, lineno).strip()
+        if line is None:
+            line = linecache.getline(filename, lineno).strip()
         if line:
             s += "    %s\n" % line
         s += "%s: %s\n>>> " % (category.__name__, message)
         return s
     warnings.formatwarning = idle_formatwarning
 
+def _callback(func, *myargs):
+    def w(*args):
+        return func(*(args + myargs))
+    return w
+
 def extended_linecache_checkcache(filename=None,
                                   orig_checkcache=linecache.checkcache):
     """Extend linecache.checkcache to preserve the <pyshell#...> entries
@@ -108,59 +115,67 @@
 class PyShellEditorWindow(EditorWindow):
     "Regular text edit window in IDLE, supports breakpoints"
 
+    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
+                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
+
     def __init__(self, *args):
-        self.breakpoints = []
+        #self.breakpoints = []
         EditorWindow.__init__(self, *args)
-        # XXX more things to be done after page is created
-        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
-        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
-        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
+
+        self.top.bind('<<tab-created>>', self._configure_new_tab)
+        self._configure_new_tab()
 
         self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
-                                           'breakpoints.lst')
+            'breakpoints.lst')
+
+    def _configure_new_tab(self, event=None):
+        page = self.text_notebook.last_page().editpage
+        page.breakpoints = []
+        text = page.text
+
+        text.bind("<<set-breakpoint-here>>",
+            _callback(self._set_breakpoint_here, text, page))
+        text.bind("<<clear-breakpoint-here>>",
+            _callback(self._clear_breakpoint_here, text, page))
+        text.bind("<<open-python-shell>>", self.flist.open_shell)
+
         # whenever a file is changed, restore breakpoints
-        if self.io.filename: self.restore_file_breaks()
-        def filename_changed_hook(old_hook=self.io.filename_change_hook,
+        if page.io.filename: self.restore_file_breaks(text, page)
+        def filename_changed_hook(old_hook=page.io.filename_change_hook,
                                   self=self):
-            self.restore_file_breaks()
+            self.restore_file_breaks(text, page)
             old_hook()
-        self.io.set_filename_change_hook(filename_changed_hook)
+        page.io.set_filename_change_hook(filename_changed_hook)
 
-    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
-                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
-
-    def set_breakpoint(self, lineno):
-        text = self.text
-        filename = self.io.filename
+    def set_breakpoint(self, lineno, text, page):
+        filename = page.io.filename
         text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
         try:
-            i = self.breakpoints.index(lineno)
+            i = page.breakpoints.index(lineno)
         except ValueError:  # only add if missing, i.e. do once
-            self.breakpoints.append(lineno)
+            page.breakpoints.append(lineno)
         try:    # update the subprocess debugger
             debug = self.flist.pyshell.interp.debugger
             debug.set_breakpoint_here(filename, lineno)
         except: # but debugger may not be active right now....
             pass
 
-    def set_breakpoint_here(self, event=None):
-        text = self.text
-        filename = self.io.filename
+    def _set_breakpoint_here(self, event=None, text=None, page=None):
+        filename = page.io.filename
         if not filename:
             text.bell()
             return
         lineno = int(float(text.index("insert")))
-        self.set_breakpoint(lineno)
+        self.set_breakpoint(lineno, text, page)
 
-    def clear_breakpoint_here(self, event=None):
-        text = self.text
-        filename = self.io.filename
+    def _clear_breakpoint_here(self, event=None, text=None, page=None):
+        filename = page.io.filename
         if not filename:
             text.bell()
             return
         lineno = int(float(text.index("insert")))
         try:
-            self.breakpoints.remove(lineno)
+            page.breakpoints.remove(lineno)
         except:
             pass
         text.tag_remove("BREAK", "insert linestart",\
@@ -172,13 +187,17 @@
             pass
 
     def clear_file_breaks(self):
-        if self.breakpoints:
-            text = self.text
-            filename = self.io.filename
+        for page in self.text_notebook.pages.itervalues():
+            page = page.editpage
+            text = page.text
+            filename = page.io.filename
+
+            if not page.breakpoints:
+                continue
             if not filename:
                 text.bell()
-                return
-            self.breakpoints = []
+                continue
+            page.breakpoints = []
             text.tag_remove("BREAK", "1.0", END)
             try:
                 debug = self.flist.pyshell.interp.debugger
@@ -186,7 +205,7 @@
             except:
                 pass
 
-    def store_file_breaks(self):
+    def store_file_breaks(self, page):
         "Save breakpoints when file is saved"
         # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
         #     be run.  The breaks are saved at that time.  If we introduce
@@ -209,8 +228,8 @@
         #     debugger is loaded) is updated during the save, the visible
         #     breaks stay synched with the subprocess even if one of these
         #     unexpected breakpoint deletions occurs.
-        breaks = self.breakpoints
-        filename = self.io.filename
+        breaks = page.breakpoints
+        filename = page.io.filename
         try:
             lines = open(self.breakpointPath,"r").readlines()
         except IOError:
@@ -219,31 +238,31 @@
         for line in lines:
             if not line.startswith(filename + '='):
                 new_file.write(line)
-        self.update_breakpoints()
-        breaks = self.breakpoints
+        self.update_breakpoints(page)
+        breaks = page.breakpoints
         if breaks:
             new_file.write(filename + '=' + str(breaks) + '\n')
         new_file.close()
 
-    def restore_file_breaks(self):
-        self.text.update()   # this enables setting "BREAK" tags to be visible
-        filename = self.io.filename
+    def restore_file_breaks(self, text, page):
+        text.update()   # this enables setting "BREAK" tags to be visible
+        filename = page.io.filename
         if filename is None:
             return
         if os.path.isfile(self.breakpointPath):
-            lines = open(self.breakpointPath,"r").readlines()
+            lines = open(self.breakpointPath, "r").readlines()
             for line in lines:
                 if line.startswith(filename + '='):
                     breakpoint_linenumbers = eval(line[len(filename)+1:])
                     for breakpoint_linenumber in breakpoint_linenumbers:
-                        self.set_breakpoint(breakpoint_linenumber)
+                        self.set_breakpoint(breakpoint_linenumber, text, page)
 
-    def update_breakpoints(self):
-        "Retrieves all the breakpoints in the current window"
-        text = self.text
+    def update_breakpoints(self, page):
+        "Retrieves all the breakpoints in the current page"
+        text = page.text
         ranges = text.tag_ranges("BREAK")
         linenumber_list = self.ranges_to_linenumbers(ranges)
-        self.breakpoints = linenumber_list
+        page.breakpoints = linenumber_list
 
     def ranges_to_linenumbers(self, ranges):
         lines = []
@@ -829,20 +848,10 @@
         self.indentwidth = 8
         self.context_use_ps1 = True
         #
-        text = self.text
-        # XXX needs to be done after a page is created
-        text.configure(wrap="char")
-        text.bind("<<newline-and-indent>>", self.enter_callback)
-        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
-        text.bind("<<interrupt-execution>>", self.cancel_callback)
-        text.bind("<<end-of-file>>", self.eof_callback)
-        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
-        text.bind("<<toggle-debugger>>", self.toggle_debugger)
-        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
-        if use_subprocess:
-            text.bind("<<view-restart>>", self.view_restart_mark)
-            text.bind("<<restart-shell>>", self.restart_shell)
-        #
+        self.text = None
+        self.textpage = None
+        self._configure_new_tab()
+
         self.save_stdout = sys.stdout
         self.save_stderr = sys.stderr
         self.save_stdin = sys.stdin
@@ -854,14 +863,37 @@
             sys.stdout = self.stdout
             sys.stderr = self.stderr
             sys.stdin = self
-        #
-        self.history = self.History(self.text)
-        #
+
         self.pollinterval = 50  # millisec
 
         if TTK:
             self.set_theme(Style(self.root))
 
+    def _configure_new_tab(self, event=None):
+        # select the last page (the one added)
+        page = self.text_notebook.last_page().editpage
+        self.text = text = page.text
+        self.textpage = page
+
+        text.configure(wrap="char")
+        text.bind("<<newline-and-indent>>",
+            _callback(self._enter_callback, text))
+        text.bind("<<plain-newline-and-indent>>",
+            _callback(self._linefeed_callback, text))
+        text.bind("<<interrupt-execution>>",
+            _callback(self._cancel_callback, text))
+        text.bind("<<end-of-file>>",
+            _callback(self._eof_callback, text))
+        text.bind("<<toggle-debugger>>", self._toggle_debugger)
+        text.bind("<<toggle-jit-stack-viewer>>", self._toggle_jit_stack_viewer)
+        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
+        if use_subprocess:
+            text.bind("<<view-restart>>",
+                _callback(self._view_restart_mark, text))
+            text.bind("<<restart-shell>>", self.restart_shell)
+
+        page.history = self.History(text)
+
     def get_standard_extension_names(self):
         return idleConf.GetExtensions(shell_only=True)
 
@@ -882,11 +914,11 @@
         ttkstyle.theme_use(idleConf.GetOption('main', 'Theme',
             'displaytheme'))
 
-    def toggle_debugger(self, event=None):
+    def _toggle_debugger(self, event=None):
         if self.executing:
             tkMessageBox.showerror("Don't debug now",
                 "You can only toggle the debugger when idle",
-                master=self.text)
+                master=self.text_notebook)
             self.set_debugger_indicator()
             return "break"
         else:
@@ -900,7 +932,7 @@
         db = self.interp.getdebugger()
         self.setvar("<<toggle-debugger>>", not not db)
 
-    def toggle_jit_stack_viewer(self, event=None):
+    def _toggle_jit_stack_viewer(self, event=None):
         pass # All we need is the variable
 
     def close_debugger(self):
@@ -946,7 +978,7 @@
                 "Kill?",
                 "The program is still running!\n Do you want to kill it?",
                 default="ok",
-                parent=self.text)
+                parent=self.text_notebook)
             if response is False:
                 return "cancel"
         if self.reading:
@@ -954,7 +986,7 @@
         self.canceled = True
         self.closing = True
         # Wait for poll_subprocess() rescheduling to stop
-        self.text.after(2 * self.pollinterval, self.close2)
+        self.text_notebook.after(2 * self.pollinterval, self.close2)
 
     def close2(self):
         return EditorWindow.close(self)
@@ -972,7 +1004,9 @@
         self.interp = None
         self.console = None
         self.flist.pyshell = None
-        self.history = None
+        for page in self.text_notebook.pages.itervalues():
+            page.editpage.history = None
+
         EditorWindow._close(self)
 
     def ispythonsource(self, filename):
@@ -1012,38 +1046,12 @@
         Tkinter._default_root = None # 03Jan04 KBK What's this?
         return True
 
-    def readline(self):
-        save = self.reading
-        try:
-            self.reading = 1
-            self.top.mainloop()  # nested mainloop()
-        finally:
-            self.reading = save
-        line = self.text.get("iomark", "end-1c")
-        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
-            line = "\n"
-        if isinstance(line, unicode):
-            import IOBinding
-            try:
-                line = line.encode(IOBinding.encoding)
-            except UnicodeError:
-                pass
-        self.resetoutput()
-        if self.canceled:
-            self.canceled = 0
-            if not use_subprocess:
-                raise KeyboardInterrupt
-        if self.endoffile:
-            self.endoffile = 0
-            line = ""
-        return line
-
     def isatty(self):
         return True
 
-    def cancel_callback(self, event=None):
+    def _cancel_callback(self, event=None, text=None):
         try:
-            if self.text.compare("sel.first", "!=", "sel.last"):
+            if text.compare("sel.first", "!=", "sel.last"):
                 return # Active selection -- always use default binding
         except:
             pass
@@ -1063,11 +1071,11 @@
             self.top.quit()  # exit the nested mainloop() in readline()
         return "break"
 
-    def eof_callback(self, event):
+    def _eof_callback(self, event, text):
         if self.executing and not self.reading:
             return # Let the default binding (delete next char) take over
-        if not (self.text.compare("iomark", "==", "insert") and
-                self.text.compare("insert", "==", "end-1c")):
+        if not (text.compare("iomark", "==", "insert") and
+                text.compare("insert", "==", "end-1c")):
             return # Let the default binding (delete next char) take over
         if not self.executing:
             self.resetoutput()
@@ -1078,24 +1086,24 @@
             self.top.quit()
         return "break"
 
-    def linefeed_callback(self, event):
+    def _linefeed_callback(self, event, text):
         # Insert a linefeed without entering anything (still autoindented)
         if self.reading:
-            self.text.insert("insert", "\n")
-            self.text.see("insert")
+            text.insert("insert", "\n")
+            text.see("insert")
         else:
             self.newline_and_indent_event(event)
         return "break"
 
-    def enter_callback(self, event):
+    def _enter_callback(self, event, text):
         if self.executing and not self.reading:
             return # Let the default binding (insert '\n') take over
         # If some text is selected, recall the selection
         # (but only if this before the I/O mark)
         try:
-            sel = self.text.get("sel.first", "sel.last")
+            sel = text.get("sel.first", "sel.last")
             if sel:
-                if self.text.compare("sel.last", "<=", "iomark"):
+                if text.compare("sel.last", "<=", "iomark"):
                     self.recall(sel, event)
                     return "break"
         except:
@@ -1103,51 +1111,52 @@
         # If we're strictly before the line containing iomark, recall
         # the current line, less a leading prompt, less leading or
         # trailing whitespace
-        if self.text.compare("insert", "<", "iomark linestart"):
+        if text.compare("insert", "<", "iomark linestart"):
             # Check if there's a relevant stdin range -- if so, use it
-            prev = self.text.tag_prevrange("stdin", "insert")
-            if prev and self.text.compare("insert", "<", prev[1]):
-                self.recall(self.text.get(prev[0], prev[1]), event)
+            prev = text.tag_prevrange("stdin", "insert")
+            if prev and text.compare("insert", "<", prev[1]):
+                self.recall(text.get(prev[0], prev[1]), event)
                 return "break"
-            next = self.text.tag_nextrange("stdin", "insert")
-            if next and self.text.compare("insert lineend", ">=", next[0]):
-                self.recall(self.text.get(next[0], next[1]), event)
+            next = text.tag_nextrange("stdin", "insert")
+            if next and text.compare("insert lineend", ">=", next[0]):
+                self.recall(text.get(next[0], next[1]), event)
                 return "break"
             # No stdin mark -- just get the current line, less any prompt
-            indices = self.text.tag_nextrange("console", "insert linestart")
+            indices = text.tag_nextrange("console", "insert linestart")
             if indices and \
-               self.text.compare(indices[0], "<=", "insert linestart"):
-                self.recall(self.text.get(indices[1], "insert lineend"), event)
+               text.compare(indices[0], "<=", "insert linestart"):
+                self.recall(text.get(indices[1], "insert lineend"), event)
             else:
-                self.recall(self.text.get("insert linestart", "insert lineend"), event)
+                self.recall(text.get("insert linestart", "insert lineend"),
+                    event)
             return "break"
         # If we're between the beginning of the line and the iomark, i.e.
         # in the prompt area, move to the end of the prompt
-        if self.text.compare("insert", "<", "iomark"):
-            self.text.mark_set("insert", "iomark")
+        if text.compare("insert", "<", "iomark"):
+            text.mark_set("insert", "iomark")
         # If we're in the current input and there's only whitespace
         # beyond the cursor, erase that whitespace first
-        s = self.text.get("insert", "end-1c")
+        s = text.get("insert", "end-1c")
         if s and not s.strip():
-            self.text.delete("insert", "end-1c")
+            text.delete("insert", "end-1c")
         # If we're in the current input before its last line,
         # insert a newline right at the insert point
-        if self.text.compare("insert", "<", "end-1c linestart"):
+        if text.compare("insert", "<", "end-1c linestart"):
             self.newline_and_indent_event(event)
             return "break"
         # We're in the last line; append a newline and submit it
-        self.text.mark_set("insert", "end-1c")
+        text.mark_set("insert", "end-1c")
         if self.reading:
-            self.text.insert("insert", "\n")
-            self.text.see("insert")
+            text.insert("insert", "\n")
+            text.see("insert")
         else:
             self.newline_and_indent_event(event)
-        self.text.tag_add("stdin", "iomark", "end-1c")
-        self.text.update_idletasks()
+        text.tag_add("stdin", "iomark", "end-1c")
+        text.update_idletasks()
         if self.reading:
             self.top.quit() # Break out of recursive mainloop() in raw_input()
         else:
-            self.runit()
+            self._runit(text)
         return "break"
 
     def recall(self, s, event):
@@ -1176,8 +1185,8 @@
             self.text.see("insert")
             self.text.undo_block_stop()
 
-    def runit(self):
-        line = self.text.get("iomark", "end-1c")
+    def _runit(self, text):
+        line = text.get("iomark", "end-1c")
         # Strip off last newline and surrounding whitespace.
         # (To allow you to hit return twice to end a statement.)
         i = len(line)
@@ -1199,14 +1208,14 @@
             tkMessageBox.showerror("No stack trace",
                 "There is no stack trace yet.\n"
                 "(sys.last_traceback is not defined)",
-                master=self.text)
+                master=self.text_notebook)
             return
         from StackViewer import StackBrowser
         sv = StackBrowser(self.root, self.flist)
 
-    def view_restart_mark(self, event=None):
-        self.text.see("iomark")
-        self.text.see("restart")
+    def _view_restart_mark(self, event=None, text=None):
+        text.see("iomark")
+        text.see("restart")
 
     def restart_shell(self, event=None):
         self.interp.restart_subprocess()
@@ -1226,8 +1235,8 @@
 
     def resetoutput(self):
         source = self.text.get("iomark", "end-1c")
-        if self.history:
-            self.history.history_store(source)
+        if self.textpage.history:
+            self.textpage.history.history_store(source)
         if self.text.get("end-2c") != "\n":
             self.text.insert("end-1c", "\n")
         self.text.mark_set("iomark", "end-1c")

Modified: sandbox/trunk/ttk-gsoc/src/idlelib/run.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib/run.py	(original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib/run.py	Wed Jul 30 14:34:19 2008
@@ -24,11 +24,13 @@
 except ImportError:
     pass
 else:
-    def idle_formatwarning_subproc(message, category, filename, lineno):
+    def idle_formatwarning_subproc(message, category, filename, lineno,
+        line=None):
         """Format warnings the IDLE way"""
         s = "\nWarning (from warnings module):\n"
         s += '  File \"%s\", line %s\n' % (filename, lineno)
-        line = linecache.getline(filename, lineno).strip()
+        if line is None:
+            line = linecache.getline(filename, lineno).strip()
         if line:
             s += "    %s\n" % line
         s += "%s: %s\n" % (category.__name__, message)


More information about the Python-checkins mailing list