Commits

Amaury Forgeot d'Arc committed be161e2

Update pyrepl from upstream (py3k-readline branch)

Comments (0)

Files changed (20)

lib_pypy/pyrepl/_minimal_curses.py

+"""Minimal '_curses' module, the low-level interface for curses module
+which is not meant to be used directly.
+
+Based on ctypes.  It's too incomplete to be really called '_curses', so
+to use it, you have to import it and stick it in sys.modules['_curses']
+manually.
+
+Note that there is also a built-in module _minimal_curses which will
+hide this one if compiled in.
+"""
+
+import ctypes, ctypes.util
+
+class error(Exception):
+    pass
+
+
+def _find_clib():
+    trylibs = ['ncurses', 'curses']
+
+    for lib in trylibs:
+        path = ctypes.util.find_library(lib)
+        if path:
+            return path
+    raise ImportError("curses library not found")
+
+_clibpath = _find_clib()
+clib = ctypes.cdll.LoadLibrary(_clibpath)
+
+clib.setupterm.argtypes = [ctypes.c_char_p, ctypes.c_int,
+                           ctypes.POINTER(ctypes.c_int)]
+clib.setupterm.restype = ctypes.c_int
+
+clib.tigetstr.argtypes = [ctypes.c_char_p]
+clib.tigetstr.restype = ctypes.POINTER(ctypes.c_char)
+
+clib.tparm.argtypes = [ctypes.c_char_p] + 9 * [ctypes.c_int]
+clib.tparm.restype = ctypes.c_char_p
+
+OK = 0
+ERR = -1
+
+# ____________________________________________________________
+
+try: from __pypy__ import builtinify
+except ImportError: builtinify = lambda f: f
+
+@builtinify
+def setupterm(termstr, fd):
+    err = ctypes.c_int(0)
+    result = clib.setupterm(termstr, fd, ctypes.byref(err))
+    if result == ERR:
+        raise error("setupterm() failed (err=%d)" % err.value)
+
+@builtinify
+def tigetstr(cap):
+    if not isinstance(cap, bytes):
+        cap = cap.encode('ascii')
+    result = clib.tigetstr(cap)
+    if ctypes.cast(result, ctypes.c_void_p).value == ERR:
+        return None
+    return ctypes.cast(result, ctypes.c_char_p).value
+
+@builtinify
+def tparm(str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0):
+    result = clib.tparm(str, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+    if result is None:
+        raise error("tparm() returned NULL")
+    return result

lib_pypy/pyrepl/cmdrepl.py

 which is in fact done by the `pythoni' script that comes with
 pyrepl."""
 
-from __future__ import nested_scopes
+from __future__ import print_function
 
 from pyrepl import completing_reader as cr, reader, completer
 from pyrepl.completing_reader import CompletingReader as CR
             if intro is not None:
                 self.intro = intro
             if self.intro:
-                print self.intro
+                print(self.intro)
             stop = None
             while not stop:
                 if self.cmdqueue:

lib_pypy/pyrepl/commands.py

 class Command(object):
     finish = 0
     kills_digit_arg = 1
-    def __init__(self, reader, cmd):
+
+    def __init__(self, reader, event_name, event):
         self.reader = reader
-        self.event_name, self.event = cmd
+        self.event = event
+        self.event_name = event_name
+
     def do(self):
         pass
 

lib_pypy/pyrepl/completer.py

 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-import __builtin__
+try:
+    import __builtin__ as builtins
+except ImportError:
+    import builtins
 
 class Completer:
     def __init__(self, ns):
         """
         import keyword
         matches = []
-        n = len(text)
         for list in [keyword.kwlist,
-                     __builtin__.__dict__.keys(),
+                     builtins.__dict__.keys(),
                      self.ns.keys()]:
             for word in list:
-                if word[:n] == text and word != "__builtins__":
+                if word.startswith(text) and word != "__builtins__":
                     matches.append(word)
         return matches
 

lib_pypy/pyrepl/completing_reader.py

             r.insert(completions[0][len(stem):])
         else:
             p = prefix(completions, len(stem))
-            if p <> '':
+            if p:
                 r.insert(p)
             if r.last_command_is(self.__class__):
                 if not r.cmpltn_menu_vis:
         p = self.pos - 1
         while p >= 0 and st.get(b[p], SW) == SW:
             p -= 1
-        return u''.join(b[p+1:self.pos])
+        return ''.join(b[p+1:self.pos])
 
     def get_completions(self, stem):
         return []

lib_pypy/pyrepl/console.py

 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-class Event:
+class Event(object):
     """An Event.  `evt' is 'key' or somesuch."""
+    __slots__ = 'evt', 'data', 'raw'
 
     def __init__(self, evt, data, raw=''):
         self.evt = evt
     def __repr__(self):
         return 'Event(%r, %r)'%(self.evt, self.data)
 
-class Console:
+class Console(object):
     """Attributes:
 
     screen,

lib_pypy/pyrepl/copy_code.py

 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-import new
+from types import CodeType
 
 def copy_code_with_changes(codeobject,
                            argcount=None,
     if name        is None: name        = codeobject.co_name
     if firstlineno is None: firstlineno = codeobject.co_firstlineno
     if lnotab      is None: lnotab      = codeobject.co_lnotab
-    return new.code(argcount,
+    return CodeType(argcount,
                     nlocals,
                     stacksize,
                     flags,

lib_pypy/pyrepl/curses.py

 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# Some try-import logic for two purposes: avoiding to bring in the whole
-# pure Python curses package if possible; and, in _curses is not actually
-# present, falling back to _minimal_curses (which is either a ctypes-based
-# pure Python module or a PyPy built-in module).
+
+import imp
+
 try:
-    import _curses
+    # Forces import of the builtin module.  Seems necessary with PyPy.
+    _curses = imp.init_builtin('_minimal_curses')
+    if not _curses:
+        raise ImportError
+    setupterm = _curses.setupterm
+    tigetstr = _curses.tigetstr
+    tparm = _curses.tparm
+    error = _curses.error
 except ImportError:
-    try:
-        import _minimal_curses as _curses
-    except ImportError:
-        # Who knows, maybe some environment has "curses" but not "_curses".
-        # If not, at least the following import gives a clean ImportError.
-        import _curses
-
-setupterm = _curses.setupterm
-tigetstr = _curses.tigetstr
-tparm = _curses.tparm
-error = _curses.error
+    raise
+    from ._minimal_curses import setupterm, tigetstr, tparm, error

lib_pypy/pyrepl/historical_reader.py

      (r'\C-g', 'isearch-cancel'),
      (r'\<backspace>', 'isearch-backspace')])
 
-del c
+if 'c' in globals():
+    del c
 
 ISEARCH_DIRECTION_NONE = ''
 ISEARCH_DIRECTION_BACKWARDS = 'r'
         self.dirty = 1
 
     def get_item(self, i):
-        if i <> len(self.history):
+        if i != len(self.history):
             return self.transient_history.get(i, self.history[i])
         else:
             return self.transient_history.get(i, self.get_unicode())
             raise
 
     def get_prompt(self, lineno, cursor_on_line):
-        if cursor_on_line and self.isearch_direction <> ISEARCH_DIRECTION_NONE:
+        if cursor_on_line and self.isearch_direction != ISEARCH_DIRECTION_NONE:
             d = 'rf'[self.isearch_direction == ISEARCH_DIRECTION_FORWARDS]
             return "(%s-search `%s') "%(d, self.isearch_term)
         else:

lib_pypy/pyrepl/input.py

 # executive, temporary decision: [tab] and [C-i] are distinct, but
 # [meta-key] is identified with [esc key].  We demand that any console
 # class does quite a lot towards emulating a unix terminal.
+from __future__ import print_function
+import unicodedata
+from collections import deque
 
-from pyrepl import unicodedata_
 
 class InputTranslator(object):
     def push(self, evt):
     def empty(self):
         pass
 
+
 class KeymapTranslator(InputTranslator):
+
     def __init__(self, keymap, verbose=0,
                  invalid_cls=None, character_cls=None):
         self.verbose = verbose
         if self.verbose:
             print(d)
         self.k = self.ck = compile_keymap(d, ())
-        self.results = []
+        self.results = deque()
         self.stack = []
+
     def push(self, evt):
         if self.verbose:
             print("pushed", evt.data, end='')
             if d is None:
                 if self.verbose:
                     print("invalid")
-                if self.stack or len(key) > 1 or unicodedata_.category(key) == 'C':
+                if self.stack or len(key) > 1 or unicodedata.category(key) == 'C':
                     self.results.append(
                         (self.invalid_cls, self.stack + [key]))
                 else:
                 self.results.append((d, self.stack + [key]))
             self.stack = []
             self.k = self.ck
+
     def get(self):
         if self.results:
-            return self.results.pop(0)
+            return self.results.popleft()
         else:
             return None
+
     def empty(self):
         return not self.results

lib_pypy/pyrepl/keymap.py

     while not ret and s < len(key):
         if key[s] == '\\':
             c = key[s+1].lower()
-            if _escapes.has_key(c):
+            if c in _escapes:
                 ret = _escapes[c]
                 s += 2
             elif c == "c":
                 if t == -1:
                     raise KeySpecError(
                               "unterminated \\< starting at char %d of %s"%(
-                        s + 1, repr(key)))                        
+                        s + 1, repr(key)))
                 ret = key[s+2:t].lower()
                 if ret not in _keynames:
                     raise KeySpecError(
         r.extend(k)
     return r
 
-def compile_keymap(keymap, empty=''):
+def compile_keymap(keymap, empty=b''):
     r = {}
     for key, value in keymap.items():
-        r.setdefault(key[0], {})[key[1:]] = value
+        if isinstance(key, bytes):
+            first = key[:1]
+        else:
+            first = key[0]
+        r.setdefault(first, {})[key[1:]] = value
     for key, value in r.items():
         if empty in value:
-            if len(value) <> 1:
+            if len(value) != 1:
                 raise KeySpecError(
                       "key definitions for %s clash"%(value.values(),))
             else:

lib_pypy/pyrepl/module_lister.py

 def _make_module_list():
     import imp
     suffs = [x[0] for x in imp.get_suffixes() if x[0] != '.pyc']
-    def compare(x, y):
-        c = -cmp(len(x), len(y))
-        if c:
-            return c
-        else:
-            return -cmp(x, y)
-    suffs.sort(compare)
+    suffs.sort(reverse=True)
     _packages[''] = list(sys.builtin_module_names)
     for dir in sys.path:
         if dir == '':
     try:
         mods = _packages[pack]
     except KeyError:
-        raise ImportError, "can't find \"%s\" package"%pack
+        raise ImportError("can't find \"%s\" package" % pack)
     return [mod for mod in mods if mod.startswith(stem)]

lib_pypy/pyrepl/pygame_console.py

         s.fill(c, [0, 600 - bmargin, 800, bmargin])
         s.fill(c, [800 - rmargin, 0, lmargin, 600])
 
-    def refresh(self, screen, cxy):
+    def refresh(self, screen, (cx, cy)):
         self.screen = screen
         self.pygame_screen.fill(colors.bg,
                                 [0, tmargin + self.cur_top + self.scroll,
 
         line_top = self.cur_top
         width, height = self.fontsize
-        self.cxy = cxy
-        cp = self.char_pos(*cxy)
+        self.cxy = (cx, cy)
+        cp = self.char_pos(cx, cy)
         if cp[1] < tmargin:
             self.scroll = - (cy*self.fh + self.cur_top)
             self.repaint()
             self.scroll += (600 - bmargin) - (cp[1] + self.fh)
             self.repaint()
         if self.curs_vis:
-            self.pygame_screen.blit(self.cursor, self.char_pos(*cxy))
+            self.pygame_screen.blit(self.cursor, self.char_pos(cx, cy))
         for line in screen:
             if 0 <= line_top + self.scroll <= (600 - bmargin - tmargin - self.fh):
                 if line:

lib_pypy/pyrepl/python_reader.py

 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 # one impressive collections of imports:
+from __future__ import print_function
+from __future__ import unicode_literals
 from pyrepl.completing_reader import CompletingReader
 from pyrepl.historical_reader import HistoricalReader
 from pyrepl import completing_reader, reader
-from pyrepl import copy_code, commands, completer
+from pyrepl import commands, completer
 from pyrepl import module_lister
-import new, sys, os, re, code, traceback
+import imp, sys, os, re, code, traceback
 import atexit, warnings
+
 try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
+    unicode
+except:
+    unicode = str
+
 try:
-    import imp
     imp.find_module("twisted")
-    from twisted.internet import reactor
-    from twisted.internet.abstract import FileDescriptor
 except ImportError:
     default_interactmethod = "interact"
 else:
     """this function eats warnings, if you were wondering"""
     pass
 
+if sys.version_info >= (3,0):
+    def _reraise(cls, val, tb):
+        __tracebackhide__ = True
+        assert hasattr(val, '__traceback__')
+        raise val
+else:
+    exec ("""
+def _reraise(cls, val, tb):
+    __tracebackhide__ = True
+    raise cls, val, tb
+""")
+
+
+
+
 class maybe_accept(commands.Command):
     def do(self):
         r = self.reader
         text = r.get_unicode()
         try:
             # ooh, look at the hack:
-            code = r.compiler("#coding:utf-8\n"+text.encode('utf-8'))
+            code = r.compiler(text)
         except (OverflowError, SyntaxError, ValueError):
             self.finish = 1
         else:
 import_line_prog = re.compile(
     "^(?:import|from)\s+(?P<mod>[A-Za-z_.0-9]*)\s*$")
 
-def mk_saver(reader):
-    def saver(reader=reader):
-        try:
-            file = open(os.path.expanduser("~/.pythoni.hist"), "w")
-        except IOError:
-            pass
-        else:
-            pickle.dump(reader.history, file)
-            file.close()
-    return saver
+def saver(reader=reader):
+    try:
+        with open(os.path.expanduser("~/.pythoni.hist"), "wb") as fp:
+            fp.write(b'\n'.join(item.encode('unicode_escape')
+                                for item in reader.history))
+    except IOError as e:
+        print(e)
+        pass
 
 class PythonicReader(CompletingReader, HistoricalReader):
     def collect_keymap(self):
         else:
             self.compiler = compiler
         try:
-            file = open(os.path.expanduser("~/.pythoni.hist"))
+            file = open(os.path.expanduser("~/.pythoni.hist"), 'rb')
         except IOError:
-            pass
+            self.history = []
         else:
             try:
-                self.history = pickle.load(file)
+                lines = file.readlines()
+                self.history = [ x.rstrip(b'\n').decode('unicode_escape') for x in lines]
             except:
                 self.history = []
             self.historyi = len(self.history)
             file.close()
-        atexit.register(mk_saver(self))
+        atexit.register(lambda: saver(self))
         for c in [maybe_accept]:
             self.commands[c.__name__] = c
             self.commands[c.__name__.replace('_', '-')] = c        
     def execute(self, text):
         try:
             # ooh, look at the hack:            
-            code = self.compile("# coding:utf8\n"+text.encode('utf-8'),
-                                '<input>', 'single')
+            code = self.compile(text, '<input>', 'single')
         except (OverflowError, SyntaxError, ValueError):
             self.showsyntaxerror("<input>")
         else:
             self.runcode(code)
-            sys.stdout.flush()
+            if sys.stdout and not sys.stdout.closed:
+                sys.stdout.flush()
 
     def interact(self):
         while 1:
                     finally:
                         warnings.showwarning = sv
                 except KeyboardInterrupt:
-                    print "KeyboardInterrupt"
+                    print("KeyboardInterrupt")
                 else:
                     if l:
                         self.execute(l)
             r = self.reader.handle1(block)
         except KeyboardInterrupt:
             self.restore()
-            print "KeyboardInterrupt"
+            print("KeyboardInterrupt")
             self.prepare()
         else:
             if self.reader.finished:
             if self.exc_info:
                 type, value, tb = self.exc_info
                 self.exc_info = None
-                raise type, value, tb
+                _reraise(type, value, tb)
         
     def tkinteract(self):
         """Run a Tk-aware Python interactive session.
                         encoding = None
                 else:
                     encoding = None # so you get ASCII...
-            con = UnixConsole(0, 1, None, encoding)
+            con = UnixConsole(os.dup(0), os.dup(1), None, encoding)
         if print_banner:
-            print "Python", sys.version, "on", sys.platform
-            print 'Type "help", "copyright", "credits" or "license" '\
-                  'for more information.'
+            print("Python", sys.version, "on", sys.platform)
+            print('Type "help", "copyright", "credits" or "license" '\
+                  'for more information.')
         sys.path.insert(0, os.getcwd())
 
         if clear_main and __name__ != '__main__':
-            mainmod = new.module('__main__')
+            mainmod = imp.new_module('__main__')
             sys.modules['__main__'] = mainmod
         else:
             mainmod = sys.modules['__main__']

lib_pypy/pyrepl/reader.py

 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-import types
-from pyrepl import unicodedata_
+from __future__ import unicode_literals
+import unicodedata
 from pyrepl import commands
 from pyrepl import input
+try:
+    unicode
+except NameError:
+    unicode = str
+    unichr = chr
+
 
 def _make_unctrl_map():
     uc_map = {}
-    for c in map(chr, range(256)):
-        if unicodedata_.category(c)[0] <> 'C':
-            uc_map[c] = c
+    for i in range(256):
+        c = unichr(i)
+        if unicodedata.category(c)[0] != 'C':
+            uc_map[i] = c
     for i in range(32):
-        c = chr(i)
-        uc_map[c] = u'^' + chr(ord('A') + i - 1)
-    uc_map['\t'] = '    ' # display TABs as 4 characters
-    uc_map['\177'] = u'^?'
+        uc_map[i] = '^' + unichr(ord('A') + i - 1)
+    uc_map[ord(b'\t')] = '    '  # display TABs as 4 characters
+    uc_map[ord(b'\177')] = unicode('^?')
     for i in range(256):
-        c = chr(i)
-        if c not in uc_map:
-            uc_map[c] = u'\\%03o'%i
+        if i not in uc_map:
+            uc_map[i] = unicode('\\%03o') % i
     return uc_map
 
-# disp_str proved to be a bottleneck for large inputs, so it's been
-# rewritten in C; it's not required though.
-try:
-    raise ImportError # currently it's borked by the unicode support
 
-    from _pyrepl_utils import disp_str, init_unctrl_map
+def _my_unctrl(c, u=_make_unctrl_map()):
+    if c in u:
+        return u[c]
+    else:
+        if unicodedata.category(c).startswith('C'):
+            return br'\u%04x' % ord(c)
+        else:
+            return c
 
-    init_unctrl_map(_make_unctrl_map())
 
-    del init_unctrl_map
-except ImportError:
-    def _my_unctrl(c, u=_make_unctrl_map()):
-        if c in u:
-            return u[c]
-        else:
-            if unicodedata_.category(c).startswith('C'):
-                return '\\u%04x'%(ord(c),)
-            else:
-                return c
+def disp_str(buffer, join=''.join, uc=_my_unctrl):
+    """ disp_str(buffer:string) -> (string, [int])
 
-    def disp_str(buffer, join=''.join, uc=_my_unctrl):
-        """ disp_str(buffer:string) -> (string, [int])
+    Return the string that should be the printed represenation of
+    |buffer| and a list detailing where the characters of |buffer|
+    get used up.  E.g.:
 
-        Return the string that should be the printed represenation of
-        |buffer| and a list detailing where the characters of |buffer|
-        get used up.  E.g.:
+    >>> disp_str(chr(3))
+    ('^C', [1, 0])
 
-        >>> disp_str(chr(3))
-        ('^C', [1, 0])
+    the list always contains 0s or 1s at present; it could conceivably
+    go higher as and when unicode support happens."""
+    # disp_str proved to be a bottleneck for large inputs,
+    # so it needs to be rewritten in C; it's not required though.
+    s = [uc(x) for x in buffer]
+    b = []  # XXX: bytearray
+    for x in s:
+        b.append(1)
+        b.extend([0] * (len(x) - 1))
+    return join(s), b
 
-        the list always contains 0s or 1s at present; it could conceivably
-        go higher as and when unicode support happens."""
-        s = map(uc, buffer)
-        return (join(s),
-                map(ord, join(map(lambda x:'\001'+(len(x)-1)*'\000', s))))
-
-    del _my_unctrl
+del _my_unctrl
 
 del _make_unctrl_map
 
  SYNTAX_WORD,
  SYNTAX_SYMBOL] = range(3)
 
+
 def make_default_syntax_table():
     # XXX perhaps should use some unicodedata here?
     st = {}
         st[c] = SYNTAX_SYMBOL
     for c in [a for a in map(unichr, range(256)) if a.isalpha()]:
         st[c] = SYNTAX_WORD
-    st[u'\n'] = st[u' '] = SYNTAX_WHITESPACE
+    st[unicode('\n')] = st[unicode(' ')] = SYNTAX_WHITESPACE
     return st
 
 default_keymap = tuple(
      #(r'\M-\n', 'insert-nl'),
      ('\\\\', 'self-insert')] + \
     [(c, 'self-insert')
-     for c in map(chr, range(32, 127)) if c <> '\\'] + \
+     for c in map(chr, range(32, 127)) if c != '\\'] + \
     [(c, 'self-insert')
      for c in map(chr, range(128, 256)) if c.isalpha()] + \
     [(r'\<up>', 'up'),
      (r'\<end>', 'end-of-line'),         # was 'end'
      (r'\<home>', 'beginning-of-line'),  # was 'home'
      (r'\<f1>', 'help'),
-     (r'\EOF', 'end'),  # the entries in the terminfo database for xterms
-     (r'\EOH', 'home'), # seem to be wrong.  this is a less than ideal
-                        # workaround
+     (r'\EOF', 'end'),   # the entries in the terminfo database for xterms
+     (r'\EOH', 'home'),  # seem to be wrong.  this is a less than ideal
+                         # workaround
      ])
 
-del c # from the listcomps
+if 'c' in globals():  # only on python 2.x
+    del c  # from the listcomps
+
 
 class Reader(object):
     """The Reader class implements the bare bones of a command reader,
         self.commands = {}
         self.msg = ''
         for v in vars(commands).values():
-            if  ( isinstance(v, type)
-                  and issubclass(v, commands.Command)
-                  and v.__name__[0].islower() ):
+            if (isinstance(v, type)
+                and issubclass(v, commands.Command)
+                and v.__name__[0].islower()):
                 self.commands[v.__name__] = v
                 self.commands[v.__name__.replace('_', '-')] = v
         self.syntax_table = make_default_syntax_table()
             p -= ll + 1
             prompt, lp = self.process_prompt(prompt)
             l, l2 = disp_str(line)
-            wrapcount = (len(l) + lp) / w
+            wrapcount = (len(l) + lp) // w
             if wrapcount == 0:
                 screen.append(prompt + l)
-                screeninfo.append((lp, l2+[1]))
+                screeninfo.append((lp, l2 + [1]))
             else:
-                screen.append(prompt + l[:w-lp] + "\\")
-                screeninfo.append((lp, l2[:w-lp]))
-                for i in range(-lp + w, -lp + wrapcount*w, w):
-                    screen.append(l[i:i+w] +  "\\")
+                screen.append(prompt + l[:w - lp] + "\\")
+                screeninfo.append((lp, l2[:w - lp]))
+                for i in range(-lp + w, -lp + wrapcount * w, w):
+                    screen.append(l[i:i + w] + "\\")
                     screeninfo.append((0, l2[i:i + w]))
-                screen.append(l[wrapcount*w - lp:])
-                screeninfo.append((0, l2[wrapcount*w - lp:]+[1]))
+                screen.append(l[wrapcount * w - lp:])
+                screeninfo.append((0, l2[wrapcount * w - lp:] + [1]))
         self.screeninfo = screeninfo
         self.cxy = self.pos2xy(self.pos)
         if self.msg and self.msg_at_bottom:
             if e == -1:
                 break
             # Found start and end brackets, subtract from string length
-            l = l - (e-s+1)
-            out_prompt += prompt[pos:s] + prompt[s+1:e]
-            pos = e+1
+            l = l - (e - s + 1)
+            out_prompt += prompt[pos:s] + prompt[s + 1:e]
+            pos = e + 1
         out_prompt += prompt[pos:]
         return out_prompt, l
 
         st = self.syntax_table
         b = self.buffer
         p -= 1
-        while p >= 0 and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD:
+        while p >= 0 and st.get(b[p], SYNTAX_WORD) != SYNTAX_WORD:
             p -= 1
         while p >= 0 and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD:
             p -= 1
             p = self.pos
         st = self.syntax_table
         b = self.buffer
-        while p < len(b) and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD:
+        while p < len(b) and st.get(b[p], SYNTAX_WORD) != SYNTAX_WORD:
             p += 1
         while p < len(b) and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD:
             p += 1
             p = self.pos
         b = self.buffer
         p -= 1
-        while p >= 0 and b[p] <> '\n':
+        while p >= 0 and b[p] != '\n':
             p -= 1
         return p + 1
 
         if p is None:
             p = self.pos
         b = self.buffer
-        while p < len(b) and b[p] <> '\n':
+        while p < len(b) and b[p] != '\n':
             p += 1
         return p
 
         """Return what should be in the left-hand margin for line
         `lineno'."""
         if self.arg is not None and cursor_on_line:
-            return "(arg: %s) "%self.arg
+            return "(arg: %s) " % self.arg
         if "\n" in self.buffer:
             if lineno == 0:
                 res = self.ps2
         # this call sets up self.cxy, so call it first.
         screen = self.calc_screen()
         self.console.refresh(screen, self.cxy)
-        self.dirty = 0 # forgot this for a while (blush)
+        self.dirty = 0  # forgot this for a while (blush)
 
     def do_cmd(self, cmd):
         #print cmd
         if isinstance(cmd[0], str):
             cmd = self.commands.get(cmd[0],
-                                    commands.invalid_command)(self, cmd)
+                                    commands.invalid_command)(self, *cmd)
         elif isinstance(cmd[0], type):
-            cmd = cmd[0](self, cmd)
+            cmd = cmd[0](self, *cmd)
+        else:
+            return  # nothing to do
 
         cmd.do()
 
 
         while 1:
             event = self.console.get_event(block)
-            if not event: # can only happen if we're not blocking
+            if not event:  # can only happen if we're not blocking
                 return None
 
+            translate = True
+
             if event.evt == 'key':
                 self.input_trans.push(event)
             elif event.evt == 'scroll':
             elif event.evt == 'resize':
                 self.refresh()
             else:
-                pass
+                translate = False
 
-            cmd = self.input_trans.get()
+            if translate:
+                cmd = self.input_trans.get()
+            else:
+                cmd = event.evt, event.data
 
             if cmd is None:
                 if block:
     def get_buffer(self, encoding=None):
         if encoding is None:
             encoding = self.console.encoding
-        return u''.join(self.buffer).encode(self.console.encoding)
+        return self.get_unicode().encode(encoding)
 
     def get_unicode(self):
         """Return the current buffer as a unicode string."""
-        return u''.join(self.buffer)
+        return unicode('').join(self.buffer)
+
 
 def test():
     from pyrepl.unix_console import UnixConsole
     while reader.readline():
         pass
 
-if __name__=='__main__':
+if __name__ == '__main__':
     test()

lib_pypy/pyrepl/readline.py

 from pyrepl.completing_reader import CompletingReader
 from pyrepl.unix_console import UnixConsole, _error
 
+try:
+    unicode
+except NameError:
+    unicode = str
 
 ENCODING = sys.getfilesystemencoding() or 'latin1'     # XXX review
 
 # ____________________________________________________________
 
 class _ReadlineWrapper(object):
-    f_in = 0
-    f_out = 1
     reader = None
     saved_history_length = -1
     startup_hook = None
     config = ReadlineConfig()
 
+    def __init__(self):
+        self.f_in = os.dup(0)
+        self.f_ut = os.dup(1)
+
     def get_reader(self):
         if self.reader is None:
             console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING)
         except _error:
             return _old_raw_input(prompt)
         reader.ps1 = prompt
-        return reader.readline(startup_hook=self.startup_hook)
+        return reader.readline(reader, startup_hook=self.startup_hook)
 
     def multiline_input(self, more_lines, ps1, ps2, returns_unicode=False):
         """Read an input on possibly multiple lines, asking for more
         self.config.completer_delims = dict.fromkeys(string)
 
     def get_completer_delims(self):
-        chars = self.config.completer_delims.keys()
+        chars = list(self.config.completer_delims.keys())
         chars.sort()
         return ''.join(chars)
 
     def _histline(self, line):
         line = line.rstrip('\n')
+        if isinstance(line, unicode):
+            return line # on py3k
         try:
             return unicode(line, ENCODING)
         except UnicodeDecodeError:   # bah, silently fall back...
         history = self.get_reader().get_trimmed_history(maxlength)
         f = open(os.path.expanduser(filename), 'w')
         for entry in history:
-            if isinstance(entry, unicode):
+            # if we are on py3k, we don't need to encode strings before
+            # writing it to a file
+            if isinstance(entry, unicode) and sys.version_info < (3,):
                 try:
                     entry = entry.encode(ENCODING)
                 except UnicodeEncodeError:   # bah, silently fall back...
 
     else:
         # this is not really what readline.c does.  Better than nothing I guess
-        import __builtin__
-        _old_raw_input = __builtin__.raw_input
-        __builtin__.raw_input = _wrapper.raw_input
+        if sys.version_info < (3,):
+            import __builtin__
+            _old_raw_input = __builtin__.raw_input
+            __builtin__.raw_input = _wrapper.raw_input
+        else:
+            import builtins
+            _old_raw_input = builtins.input
+            builtins.input = _wrapper.raw_input
 
 _old_raw_input = None
 _setup()

lib_pypy/pyrepl/simple_interact.py

         return False
     return True
 
+
 def run_multiline_interactive_console(mainmodule=None):
     import code
-    if mainmodule is None:
-        import __main__ as mainmodule
+    import __main__
+    mainmodule = mainmodule or __main__
     console = code.InteractiveConsole(mainmodule.__dict__)
 
     def more_lines(unicodetext):
         # ooh, look at the hack:
-        src = "#coding:utf-8\n"+unicodetext.encode('utf-8')
+        if sys.version_info < (3,):
+            src = "#coding:utf-8\n"+unicodetext.encode('utf-8')
+        else:
+            src = unicodetext
         try:
             code = console.compile(src, '<input>', 'single')
         except (OverflowError, SyntaxError, ValueError):

lib_pypy/pyrepl/trace.py

+import os
+
+trace_filename = os.environ.get("PYREPL_TRACE")
+
+if trace_filename is not None:
+    trace_file = open(trace_filename, 'a')
+else:
+    trace_file = None
+
+def trace(line, *k, **kw):
+    if trace_file is None:
+        return
+    if k or kw:
+        line = line.format(*k, **kw)
+    trace_file.write(line+'\n')
+    trace_file.flush()
+

lib_pypy/pyrepl/unix_console.py

 import termios, select, os, struct, errno
 import signal, re, time, sys
 from fcntl import ioctl
-from pyrepl import curses
-from pyrepl.fancy_termios import tcgetattr, tcsetattr
-from pyrepl.console import Console, Event
-from pyrepl import unix_eventqueue
+from . import curses
+from .fancy_termios import tcgetattr, tcsetattr
+from .console import Console, Event
+from .unix_eventqueue import EventQueue
+from .trace import trace
 
 class InvalidTerminal(RuntimeError):
     pass
 
+try:
+    unicode
+except NameError:
+    unicode = str
+
 _error = (termios.error, curses.error, InvalidTerminal)
 
 # there are arguments for changing this to "refresh"
 
 del r, maybe_add_baudrate
 
-delayprog = re.compile("\\$<([0-9]+)((?:/|\\*){0,2})>")
+delayprog = re.compile(b"\\$<([0-9]+)((?:/|\\*){0,2})>")
 
 try:
     poll = select.poll
         else:
             self.output_fd = f_out.fileno()
         
+
         self.pollob = poll()
         self.pollob.register(self.input_fd, POLLIN)
         curses.setupterm(term, self.output_fd)
 
         self.__move = self.__move_short
 
-        self.event_queue = unix_eventqueue.EventQueue(self.input_fd)
-        self.partial_char = ''
+        self.event_queue = EventQueue(self.input_fd, self.encoding)
         self.cursor_visible = 1
 
     def change_encoding(self, encoding):
         self.encoding = encoding
     
-    def refresh(self, screen, cxy):
+    def refresh(self, screen, c_xy):
         # this function is still too long (over 90 lines)
-
+        cx, cy = c_xy
         if not self.__gone_tall:
             while len(self.screen) < min(len(screen), self.height):
                 self.__hide_cursor()
         old_offset = offset = self.__offset
         height = self.height
 
-        if 0:
-            global counter
-            try:
-                counter
-            except NameError:
-                counter = 0
-            self.__write_code(curses.tigetstr("setaf"), counter)
-            counter += 1
-            if counter > 8:
-                counter = 0
 
         # we make sure the cursor is on the screen, and that we're
         # using all of the screen if we can
-        cx, cy = cxy
         if cy < offset:
             offset = cy
         elif cy >= offset + height:
         self.__buffer.append((text, 0))
 
     def __write_code(self, fmt, *args):
+
         self.__buffer.append((curses.tparm(fmt, *args), 1))
 
     def __maybe_write_code(self, fmt, *args):
         self.event_queue.insert(Event('resize', None))
 
     def push_char(self, char):
-        self.partial_char += char
-        try:
-            c = unicode(self.partial_char, self.encoding)
-        except UnicodeError as e:
-            if len(e.args) > 4 and \
-                   e.args[4] == 'unexpected end of data':
-                pass
-            else:
-                # was: "raise".  But it crashes pyrepl, and by extension the
-                # pypy currently running, in which we are e.g. in the middle
-                # of some debugging session.  Argh.  Instead just print an
-                # error message to stderr and continue running, for now.
-                self.partial_char = ''
-                sys.stderr.write('\n%s: %s\n' % (e.__class__.__name__, e))
-        else:
-            self.partial_char = ''
-            self.event_queue.push(c)
+        trace('push char {char!r}', char=char)
+        self.event_queue.push(char)
         
     def get_event(self, block=1):
         while self.event_queue.empty():
                 return int(os.environ["LINES"]), int(os.environ["COLUMNS"])
             except KeyError:
                 height, width = struct.unpack(
-                    "hhhh", ioctl(self.input_fd, TIOCGWINSZ, "\000"*8))[0:2]
+                    "hhhh", ioctl(self.input_fd, TIOCGWINSZ, b"\000"*8))[0:2]
                 if not height: return 25, 80
                 return height, width
     else:
 
     if FIONREAD:
         def getpending(self):
-            e = Event('key', '', '')
+            e = Event('key', '', b'')
 
             while not self.event_queue.empty():
                 e2 = self.event_queue.get()
                 e.raw += e.raw
                 
             amount = struct.unpack(
-                "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0]
-            raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace')
-            e.data += raw
+                "i", ioctl(self.input_fd, FIONREAD, b"\0\0\0\0"))[0]
+            raw = os.read(self.input_fd, amount)
+            data = unicode(raw, self.encoding, 'replace')
+            e.data += data
             e.raw += raw
             return e
     else:
         def getpending(self):
-            e = Event('key', '', '')
+            e = Event('key', '', b'')
 
             while not self.event_queue.empty():
                 e2 = self.event_queue.get()
                 e.raw += e.raw
                 
             amount = 10000
-            raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace')
-            e.data += raw
+            raw = os.read(self.input_fd, amount)
+            data = unicode(raw, self.encoding, 'replace')
+            e.data += data
             e.raw += raw
             return e
 

lib_pypy/pyrepl/unix_eventqueue.py

 from pyrepl import keymap
 from pyrepl.console import Event
 from pyrepl import curses
+from .trace import trace
 from termios import tcgetattr, VERASE
 import os
+try:
+    unicode
+except NameError:
+    unicode = str
+
 
 _keynames = {
     "delete" : "kdch1",
     "up" : "kcuu1",
     }
 
-class EventQueue(object):
-    def __init__(self, fd):
-        our_keycodes = {}
-        for key, tiname in _keynames.items():
-            keycode = curses.tigetstr(tiname)
-            if keycode:
-                our_keycodes[keycode] = str(key)
-        if os.isatty(fd):
-            our_keycodes[tcgetattr(fd)[6][VERASE]] = u'backspace'
-        self.k = self.ck = keymap.compile_keymap(our_keycodes)
+def general_keycodes():
+    keycodes = {}
+    for key, tiname in _keynames.items():
+        keycode = curses.tigetstr(tiname)
+        trace('key {key} tiname {tiname} keycode {keycode!r}', **locals())
+        if keycode:
+            keycodes[keycode] = key
+    return keycodes
+
+
+
+def EventQueue(fd, encoding):
+    keycodes = general_keycodes()
+    if os.isatty(fd):
+        backspace = tcgetattr(fd)[6][VERASE]
+        keycodes[backspace] = unicode('backspace')
+    k = keymap.compile_keymap(keycodes)
+    trace('keymap {k!r}', k=k)
+    return EncodedQueue(k, encoding)
+
+class EncodedQueue(object):
+    def __init__(self, keymap, encoding):
+        self.k = self.ck = keymap
         self.events = []
-        self.buf = []
+        self.buf = bytearray()
+        self.encoding=encoding
+
     def get(self):
         if self.events:
             return self.events.pop(0)
         else:
             return None
+
     def empty(self):
         return not self.events
+
+    def flush_buf(self):
+        old = self.buf
+        self.buf = bytearray()
+        return bytes(old)
+
     def insert(self, event):
+        trace('added event {event}', event=event)
         self.events.append(event)
+
     def push(self, char):
+        self.buf.append(ord(char))
         if char in self.k:
+            if self.k is self.ck:
+                #sanity check, buffer is empty when a special key comes
+                assert len(self.buf) == 1
             k = self.k[char]
+            trace('found map {k!r}', k=k)
             if isinstance(k, dict):
-                self.buf.append(char)
                 self.k = k
             else:
-                self.events.append(Event('key', k, ''.join(self.buf) + char))
-                self.buf = []
+                self.insert(Event('key', k, self.flush_buf()))
                 self.k = self.ck
-        elif self.buf:
-            self.events.extend([Event('key', c, c) for c in self.buf])
-            self.buf = []
+
+        else:
+            try:
+                decoded = bytes(self.buf).decode(self.encoding)
+            except:
+                return
+
+            self.insert(Event('key', decoded, self.flush_buf()))
             self.k = self.ck
-            self.push(char)
-        else:
-            self.events.append(Event('key', char, char))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.