diff options
Diffstat (limited to 'Lib/idlelib')
| -rw-r--r-- | Lib/idlelib/ColorDelegator.py | 13 | ||||
| -rw-r--r-- | Lib/idlelib/EditorWindow.py | 19 | ||||
| -rw-r--r-- | Lib/idlelib/NEWS.txt | 7 | ||||
| -rw-r--r-- | Lib/idlelib/PathBrowser.py | 5 | ||||
| -rw-r--r-- | Lib/idlelib/PyShell.py | 16 | ||||
| -rw-r--r-- | Lib/idlelib/ScriptBinding.py | 12 | ||||
| -rw-r--r-- | Lib/idlelib/__main__.py | 9 | ||||
| -rw-r--r-- | Lib/idlelib/configHandler.py | 3 | ||||
| -rw-r--r-- | Lib/idlelib/idlever.py | 2 | ||||
| -rw-r--r-- | Lib/idlelib/rpc.py | 26 | ||||
| -rw-r--r-- | Lib/idlelib/run.py | 14 | 
11 files changed, 102 insertions, 24 deletions
diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py index e188192..e4ccb42 100644 --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -21,10 +21,11 @@ def make_pat():      # 1st 'file' colorized normal, 2nd as builtin, 3rd as string      builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"      comment = any("COMMENT", [r"#[^\n]*"]) -    sqstring = r"(\b[rRbB])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" -    dqstring = r'(\b[rRbB])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' -    sq3string = r"(\b[rRbB])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" -    dq3string = r'(\b[rRbB])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' +    stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR|rb|rB|Rb|RB)?" +    sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?" +    dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?' +    sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" +    dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'      string = any("STRING", [sq3string, dq3string, sqstring, dqstring])      return kw + "|" + builtin + "|" + comment + "|" + string +\             "|" + any("SYNC", [r"\n"]) @@ -149,9 +150,9 @@ class ColorDelegator(Delegator):              self.stop_colorizing = False              self.colorizing = True              if DEBUG: print("colorizing...") -            t0 = time.clock() +            t0 = time.perf_counter()              self.recolorize_main() -            t1 = time.clock() +            t1 = time.perf_counter()              if DEBUG: print("%.3f seconds" % (t1-t0))          finally:              self.colorizing = False diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index bec2191..6bdcecc 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1,8 +1,9 @@ -import sys +import imp +import importlib  import os  import re  import string -import imp +import sys  from tkinter import *  import tkinter.simpledialog as tkSimpleDialog  import tkinter.messagebox as tkMessageBox @@ -27,8 +28,7 @@ def _sphinx_version():      "Format sys.version_info to produce the Sphinx version string used to install the chm docs"      major, minor, micro, level, serial = sys.version_info      release = '%s%s' % (major, minor) -    if micro: -        release += '%s' % (micro,) +    release += '%s' % (micro,)      if level == 'candidate':          release += 'rc%s' % (serial,)      elif level != 'final': @@ -120,7 +120,7 @@ class EditorWindow(object):      def __init__(self, flist=None, filename=None, key=None, root=None):          if EditorWindow.help_url is None: -            dochome =  os.path.join(sys.prefix, 'Doc', 'index.html') +            dochome =  os.path.join(sys.base_prefix, 'Doc', 'index.html')              if sys.platform.count('linux'):                  # look for html docs in a couple of standard places                  pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3] @@ -131,13 +131,13 @@ class EditorWindow(object):                      dochome = os.path.join(basepath, pyver,                                             'Doc', 'index.html')              elif sys.platform[:3] == 'win': -                chmfile = os.path.join(sys.prefix, 'Doc', +                chmfile = os.path.join(sys.base_prefix, 'Doc',                                         'Python%s.chm' % _sphinx_version())                  if os.path.isfile(chmfile):                      dochome = chmfile              elif macosxSupport.runningAsOSXApp():                  # documentation is stored inside the python framework -                dochome = os.path.join(sys.prefix, +                dochome = os.path.join(sys.base_prefix,                          'Resources/English.lproj/Documentation/index.html')              dochome = os.path.normpath(dochome)              if os.path.isfile(dochome): @@ -1005,7 +1005,10 @@ class EditorWindow(object):      def load_extension(self, name):          try: -            mod = __import__(name, globals(), locals(), []) +            try: +                mod = importlib.import_module('.' + name, package=__package__) +            except ImportError: +                mod = importlib.import_module(name)          except ImportError:              print("\nFailed to import extension: ", name)              raise diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index a6b06b4..b28e58a 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,6 +1,11 @@ -What's New in IDLE 3.2.3? +What's New in IDLE 3.3?  ========================= +- Issue #8515: Set __file__ when run file in IDLE. +  Initial patch by Bruce Frederiksen. + +- IDLE can be launched as `python -m idlelib` +  - Issue #14409: IDLE now properly executes commands in the Shell window    when it cannot read the normal config files on startup and    has to use the built-in default key bindings. diff --git a/Lib/idlelib/PathBrowser.py b/Lib/idlelib/PathBrowser.py index d88a48e..9954f07 100644 --- a/Lib/idlelib/PathBrowser.py +++ b/Lib/idlelib/PathBrowser.py @@ -1,6 +1,7 @@  import os  import sys  import imp +import importlib.machinery  from idlelib.TreeWidget import TreeItem  from idlelib.ClassBrowser import ClassBrowser, ModuleBrowserTreeItem @@ -70,7 +71,9 @@ class DirBrowserTreeItem(TreeItem):      def listmodules(self, allnames):          modules = {} -        suffixes = imp.get_suffixes() +        suffixes = importlib.machinery.EXTENSION_SUFFIXES[:] +        suffixes += importlib.machinery.SOURCE_SUFFIXES[:] +        suffixes += importlib.machinery.BYTECODE_SUFFIXES[:]          sorted = []          for suff, mode, flag in suffixes:              i = -len(suff) diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index 278f4f6..9df8957 100644 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -473,6 +473,10 @@ class ModifiedInterpreter(InteractiveInterpreter):      def kill_subprocess(self):          try: +            self.rpcclt.listening_sock.close() +        except AttributeError:  # no socket +            pass +        try:              self.rpcclt.close()          except AttributeError:  # no socket              pass @@ -1000,6 +1004,8 @@ class PyShell(OutputWindow):                  return False          else:              nosub = "==== No Subprocess ====" +            sys.displayhook = rpc.displayhook +          self.write("Python %s on %s\n%s\n%s" %                     (sys.version, sys.platform, self.COPYRIGHT, nosub))          self.showprompt() @@ -1222,6 +1228,16 @@ class PyShell(OutputWindow):          self.set_line_and_column()      def write(self, s, tags=()): +        if isinstance(s, str) and len(s) and max(s) > '\uffff': +            # Tk doesn't support outputting non-BMP characters +            # Let's assume what printed string is not very long, +            # find first non-BMP character and construct informative +            # UnicodeEncodeError exception. +            for start, char in enumerate(s): +                if char > '\uffff': +                    break +            raise UnicodeEncodeError("UCS-2", char, start, start+1, +                                     'Non-BMP character not supported in Tk')          try:              self.text.mark_gravity("iomark", "right")              OutputWindow.write(self, s, tags, "iomark") diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py index 18ce965..528adf6 100644 --- a/Lib/idlelib/ScriptBinding.py +++ b/Lib/idlelib/ScriptBinding.py @@ -150,16 +150,16 @@ class ScriptBinding:          dirname = os.path.dirname(filename)          # XXX Too often this discards arguments the user just set...          interp.runcommand("""if 1: -            _filename = %r +            __file__ = {filename!r}              import sys as _sys              from os.path import basename as _basename              if (not _sys.argv or -                _basename(_sys.argv[0]) != _basename(_filename)): -                _sys.argv = [_filename] +                _basename(_sys.argv[0]) != _basename(__file__)): +                _sys.argv = [__file__]              import os as _os -            _os.chdir(%r) -            del _filename, _sys, _basename, _os -            \n""" % (filename, dirname)) +            _os.chdir({dirname!r}) +            del _sys, _basename, _os +            \n""".format(filename=filename, dirname=dirname))          interp.prepend_syspath(filename)          # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still          #         go to __stderr__.  With subprocess, they go to the shell. diff --git a/Lib/idlelib/__main__.py b/Lib/idlelib/__main__.py new file mode 100644 index 0000000..0666f2f --- /dev/null +++ b/Lib/idlelib/__main__.py @@ -0,0 +1,9 @@ +""" +IDLE main entry point + +Run IDLE as python -m idlelib +""" + + +import idlelib.PyShell +idlelib.PyShell.main() diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py index da92726..4049004 100644 --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -145,7 +145,8 @@ class IdleUserConfParser(IdleConfParser):              except IOError:                  os.unlink(fname)                  cfgFile = open(fname, 'w') -            self.write(cfgFile) +            with cfgFile: +                self.write(cfgFile)          else:              self.RemoveFile() diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py index 17455db..44811af 100644 --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1 +1 @@ -IDLE_VERSION = "3.2.3" +IDLE_VERSION = "3.3.0a4" diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index def4394..77cb3ac 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -40,6 +40,7 @@ import traceback  import copyreg  import types  import marshal +import builtins  def unpickle_code(ms): @@ -196,8 +197,12 @@ class SocketIO(object):                  return ("ERROR", "Unsupported message type: %s" % how)          except SystemExit:              raise +        except KeyboardInterrupt: +            raise          except socket.error:              raise +        except Exception as ex: +            return ("CALLEXC", ex)          except:              msg = "*** Internal Error: rpc.py:SocketIO.localcall()\n\n"\                    " Object: %s \n Method: %s \n Args: %s\n" @@ -257,6 +262,9 @@ class SocketIO(object):          if how == "ERROR":              self.debug("decoderesponse: Internal ERROR:", what)              raise RuntimeError(what) +        if how == "CALLEXC": +            self.debug("decoderesponse: Call Exception:", what) +            raise what          raise SystemError(how, what)      def decode_interrupthook(self): @@ -596,3 +604,21 @@ class MethodProxy(object):  # XXX KBK 09Sep03  We need a proper unit test for this module.  Previously  #                  existing test code was removed at Rev 1.27 (r34098). + +def displayhook(value): +    """Override standard display hook to use non-locale encoding""" +    if value is None: +        return +    # Set '_' to None to avoid recursion +    builtins._ = None +    text = repr(value) +    try: +        sys.stdout.write(text) +    except UnicodeEncodeError: +        # let's use ascii while utf8-bmp codec doesn't present +        encoding = 'ascii' +        bytes = text.encode(encoding, 'backslashreplace') +        text = bytes.decode(encoding, 'strict') +        sys.stdout.write(text) +    sys.stdout.write("\n") +    builtins._ = value diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 25338ff..7124c72 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -6,6 +6,7 @@ import traceback  import _thread as thread  import threading  import queue +import tkinter  from idlelib import CallTips  from idlelib import AutoComplete @@ -38,6 +39,17 @@ else:          return s      warnings.formatwarning = idle_formatwarning_subproc + +tcl = tkinter.Tcl() + + +def handle_tk_events(tcl=tcl): +    """Process any tk events that are ready to be dispatched if tkinter +    has been imported, a tcl interpreter has been created and tk has been +    loaded.""" +    tcl.eval("update") + +  # Thread shared globals: Establish a queue between a subthread (which handles  # the socket) and the main thread (which runs user code), plus global  # completion, exit and interruptable (the main thread) flags: @@ -93,6 +105,7 @@ def main(del_exitfunc=False):              try:                  seq, request = rpc.request_queue.get(block=True, timeout=0.05)              except queue.Empty: +                handle_tk_events()                  continue              method, args, kwargs = request              ret = method(*args, **kwargs) @@ -254,6 +267,7 @@ class MyHandler(rpc.RPCHandler):          sys.stdin = self.console = self.get_remote_proxy("stdin")          sys.stdout = self.get_remote_proxy("stdout")          sys.stderr = self.get_remote_proxy("stderr") +        sys.displayhook = rpc.displayhook          # page help() text to shell.          import pydoc # import must be done here to capture i/o binding          pydoc.pager = pydoc.plainpager  | 
