Author: Ronny Pfannschmidt <[email protected]> Branch: py3k-readline Changeset: r218:21b1a3e5cc66 Date: 2013-01-15 11:53 +0100 http://bitbucket.org/pypy/pyrepl/changeset/21b1a3e5cc66/
Log: merge default diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -1,3 +1,4 @@ 9e6ce97035736092e9eb7815816b36bee5e92cb3 pyrepl080 5f47f9f65ff7127668bdeda102e675c23224d321 pyrepl081 61de8bdd14264ab8af5b336be854cb9bfa720542 pyrepl082 +62f2256014af7b74b97c00827f1a7789e00dd814 v0.8.4 diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ This file contains more verbose descriptions of the changes between versions than those in README. +New in Version 0.8.x: + + * propper command usage + fix one wrong call (thanks Trundle) + + New in 0.7.3: + ^T at the start of a line should not crash. diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,3 @@ - Copyright 2000-2002 Michael Hudson [email protected] - - All Rights Reserved - Permission to use, copy, modify, and distribute this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both diff --git a/README b/README --- a/README +++ b/README @@ -1,6 +1,4 @@ -This is pyrepl 0.8.3, a readline-a-like in Python. - -http://pyrepl.codespeak.net/ +This is pyrepl 0.8.4, a readline-a-like in Python. It requires python 2.7 (or newer) and features: @@ -36,13 +34,6 @@ which will also install the above "pythoni" script. -Please direct comments to [email protected]. - -(If you've released open source software you'll know how frustrating -it is to see a couple of hundred downloads and only get a handful of -emails, so don't think I'll be irritated by the banality of your -comments!) - Summary of 0.8.4: diff --git a/encopyright.py b/encopyright.py deleted file mode 100644 --- a/encopyright.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/local/bin/python - -# Copyright 2000-2003 Michael Hudson [email protected] -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -import os, time, sys -import py - -header_template = """\ -# Copyright 2000-%(lastyear)s Michael Hudson-Doyle <[email protected]>%(others)s -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\ -""" - -author_template = "\n#%s%%s"%(' '*(header_template.index("Michael")+1),) - - - -author_map = { - u'mwh': None, - u'micahel': None, - u'Michael Hudson <[email protected]>': None, - u'arigo': u"Armin Rigo", - u'antocuni': u'Antonio Cuni', - u'anto': u'Antonio Cuni', - u'bob': u'Bob Ippolito', - u'fijal': u'Maciek Fijalkowski', - u'agaynor': u'Alex Gaynor', - u'hpk': u'Holger Krekel', - u'Ronny': u'Ronny Pfannschmidt', - u'amauryfa': u"Amaury Forgeot d'Arc", - } - - -def author_revs(path): - proc = py.std.subprocess.Popen([ - 'hg','log', str(path), - '--template', '{author|user} {date}\n', - '-r', 'not keyword("encopyright")', - ], stdout=py.std.subprocess.PIPE) - output, _ = proc.communicate() - lines = output.splitlines() - for line in lines: - try: - name, date = line.split(None, 1) - except ValueError: - pass - else: - if '-' in date: - date = date.split('-')[0] - yield name, float(date) - - -def process(path): - ilines = path.readlines() - revs = sorted(author_revs(path), key=lambda x:x[1]) - modified_year = time.gmtime(revs[-1][1])[0] - if not modified_year: - print 'E: no sensible modified_year found for', path - modified_year = time.gmtime(time.time())[0] - extra_authors = [] - authors = set(rev[0] for rev in revs) - for a in authors: - if a not in author_map: - print 'E: need real name for', a - ea = author_map.get(a) - if ea: - extra_authors.append(ea) - extra_authors.sort() - header = header_template % { - 'lastyear': modified_year, - 'others': ''.join([author_template%ea for ea in extra_authors]) - } - header_lines = header.splitlines() - prelines = [] - old_copyright = [] - - if not ilines: - print "W ignoring empty file", path - return - - i = 0 - - if ilines[0][:2] == '#!': - prelines.append(ilines[0]) - i += 1 - - while i < len(ilines) and not ilines[i].strip(): - prelines.append(ilines[i]) - i += 1 - - while i < len(ilines) and ilines[i][:1] == '#': - old_copyright.append(ilines[i]) - i += 1 - - if abs(len(old_copyright) - len(header_lines)) < 2 + len(extra_authors): - for x, y in zip(old_copyright, header_lines): - if x[:-1] != y: - print "C change needed in", path - ofile = path.open("w") - for l in prelines: - ofile.write(l) - ofile.write(header + "\n") - for l in ilines[i:]: - ofile.write(l) - ofile.close() - break - else: - print "M no change needed in", path - else: - print "A no (c) in", file - with path.open("w") as ofile: - for l in prelines: - ofile.write(l) - ofile.write(header + "\n\n") - for l in ilines[len(prelines):]: - ofile.write(l) - - -for thing in sys.argv[1:]: - path = py.path.local(thing) - if path.check(dir=1): - for item in path.visit('*.py'): - process(item) - elif path.check(file=1, ext='py'): - process(path) diff --git a/pyrepl/cmdrepl.py b/pyrepl/cmdrepl.py --- a/pyrepl/cmdrepl.py +++ b/pyrepl/cmdrepl.py @@ -53,8 +53,8 @@ def get_completions(self, stem): if len(stem) != self.pos: return [] - return cr.uniqify([s for s in self.completions - if s.startswith(stem)]) + return sorted(set(s for s in self.completions + if s.startswith(stem))) def replize(klass, history_across_invocations=1): diff --git a/pyrepl/completing_reader.py b/pyrepl/completing_reader.py --- a/pyrepl/completing_reader.py +++ b/pyrepl/completing_reader.py @@ -21,13 +21,6 @@ from pyrepl import commands, reader from pyrepl.reader import Reader -def uniqify(l): - d = {} - for i in l: - d[i] = 1 - r = d.keys() - r.sort() - return r def prefix(wordlist, j = 0): d = {} diff --git a/pyrepl/module_lister.py b/pyrepl/module_lister.py --- a/pyrepl/module_lister.py +++ b/pyrepl/module_lister.py @@ -17,7 +17,6 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl.completing_reader import uniqify import os, sys # for the completion support. @@ -38,9 +37,7 @@ l.append( prefix + fname ) _packages[prefix + fname] = _make_module_list_dir( file, suffs, prefix + fname + '.' ) - l = uniqify(l) - l.sort() - return l + return sorted(set(l)) def _make_module_list(): import imp diff --git a/pyrepl/python_reader.py b/pyrepl/python_reader.py --- a/pyrepl/python_reader.py +++ b/pyrepl/python_reader.py @@ -155,7 +155,7 @@ return [x[len(mod) + 1:] for x in l if x.startswith(mod + '.' + name)] try: - l = completing_reader.uniqify(self.completer.complete(stem)) + l = sorted(set(self.completer.complete(stem))) return l except (NameError, AttributeError): return [] diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -200,7 +200,7 @@ except _error: return _old_raw_input(prompt) reader.ps1 = prompt - return reader.readline(reader, startup_hook=self.startup_hook) + return reader.readline(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 diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -358,6 +358,7 @@ # per-readline preparations: self.__svtermstate = tcgetattr(self.input_fd) raw = self.__svtermstate.copy() + raw.iflag |= termios.ICRNL raw.iflag &=~ (termios.BRKINT | termios.INPCK | termios.ISTRIP | termios.IXON) raw.oflag &=~ (termios.OPOST) diff --git a/pyrepl_utilsmodule.c b/pyrepl_utilsmodule.c deleted file mode 100644 --- a/pyrepl_utilsmodule.c +++ /dev/null @@ -1,175 +0,0 @@ - -/* Copyright 2000-2001 Michael Hudson [email protected] - * - * All Rights Reserved - * - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <Python.h> - -/* nothing here that can't be done in Python, but it helps to be able - to do it quicker */ - -static char* _unctrl_map[255]; - -static PyObject* -pyrepl_utils_init_unctrl_map(PyObject* self, PyObject* args) -{ - PyObject* dict; - PyObject* pyc; - PyObject* pys; - int c = 0; - char cc; - - if (!PyArg_ParseTuple(args, "O", &dict)) { - return NULL; - } - - if (!PyDict_Check(dict)) { - PyErr_SetString(PyExc_TypeError, - "init_unctrl_map: must be dict"); - } - - for (c = 0; c < 256; c++) { - cc = c; - pyc = PyString_FromStringAndSize(&cc,1); - if (!pyc) return NULL; - pys = PyDict_GetItem(dict, pyc); - if (!pys) { - PyErr_Format(PyExc_KeyError, - "%c",cc); - _unctrl_map[0] = NULL; - return NULL; - } - if (!PyString_Check(pys)) { - PyErr_SetString(PyExc_TypeError, - "init_unctrl_map: found non-string"); - } - Py_INCREF(pys); /* this ain't going away */ - _unctrl_map[c] = PyString_AS_STRING(pys); - Py_DECREF(pyc); - } - - Py_INCREF(Py_None); - return Py_None; -} - -static char pyrepl_utils_init_unctrl_map_doc[] = -" init_unctrl_map(unctrl_map:dict) -> None\n\ -\n\ -Call this before calling disp_str."; - -static PyObject* -pyrepl_utils_disp_str(PyObject* self, PyObject* args) -{ - char *s; - char *r; - char **temp; - int slen = 0, rlen = 0; - int i, j, k, n; - PyObject *list, *ret; - - if (!PyArg_ParseTuple(args, "s#", &s, &slen)) { - return NULL; - } - - if (!_unctrl_map[0]) { - PyErr_SetString(PyExc_RuntimeError, - "bad boy!"); - return NULL; - } - - temp = malloc(sizeof(char*)*slen); - if (!temp) { - PyErr_NoMemory(); - return NULL; - } - - for (i = 0; i < slen; i++) { - temp[i] = _unctrl_map[(unsigned char)s[i]]; - rlen += strlen(temp[i]); - } - - r = malloc(rlen + 1); - if (!r) { - free(temp); - PyErr_NoMemory(); - return NULL; - } - - list = PyList_New(rlen); - if (!list) { - free(r); - free(temp); - return NULL; - } - - for (i = 0, j = 0; i < slen; i++) { - n = strlen(temp[i]); - memcpy(&r[j], temp[i], n); - PyList_SET_ITEM(list, j, PyInt_FromLong(1)); - k = j + 1; - j += n; - while (k < j) { - PyList_SET_ITEM(list, k, PyInt_FromLong(0)); - k++; - } - } - - free(temp); - r[rlen] = '\000'; - - ret = Py_BuildValue("(sN)", r, list); - - free(r); - - return ret; -} - -static char pyrepl_utils_disp_str_doc[] = -" disp_str(buffer:string) -> (string, [int])\n\ -\n\ -Return the string that should be the printed represenation of\n\ -|buffer| and a list detailing where the characters of |buffer|\n\ -get used up. E.g:\n\ -\n\ ->>> disp_str('\\003')\n\ -('^C', [1, 0])\n\ -\n\ -the list always contains 0s or 1s at present; it could conceivably\n\ -go higher as and when unicode support happens.\n\ -\n\ -You MUST call init_unctrl_map before using this version."; - - -PyMethodDef pyrepl_utils_methods[] = { - { "init_unctrl_map", pyrepl_utils_init_unctrl_map, - METH_VARARGS, pyrepl_utils_init_unctrl_map_doc }, - { "disp_str", pyrepl_utils_disp_str, - METH_VARARGS, pyrepl_utils_disp_str_doc }, - { NULL, NULL } -}; - -static char pyrepl_utils_doc[] = -"Utilities to help speed up pyrepl."; - -void init_pyrepl_utils(void) -{ - Py_InitModule3("_pyrepl_utils", - pyrepl_utils_methods, - pyrepl_utils_doc); -} diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -42,7 +42,6 @@ description = "A library for building flexible command line interfaces", platforms = ["unix", "linux"], packages = ["pyrepl" ], - #ext_modules = [Extension("_pyrepl_utils", ["pyrepl_utilsmodule.c"])], scripts = ["pythoni", "pythoni1"], long_description = long_desc, ) diff --git a/testing/test_bugs.py b/testing/test_bugs.py --- a/testing/test_bugs.py +++ b/testing/test_bugs.py @@ -17,15 +17,26 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from .infrastructure import EA, read_spec +from pyrepl.historical_reader import HistoricalReader +from .infrastructure import EA, TestReader, read_spec # this test case should contain as-verbatim-as-possible versions of # (applicable) bug reports import pytest +class HistoricalTestReader(HistoricalReader, TestReader): + pass + @pytest.mark.xfail(reason='event missing', run=False) def test_transpose_at_start(): read_spec([( 'transpose', [EA, '']), ( 'accept', [''])]) +def test_cmd_instantiation_crash(): + spec = [ + ('reverse-history-isearch', ["(r-search `') "]), + (('key', 'left'), ['']), + ('accept', ['']) + ] + read_spec(spec, HistoricalTestReader) diff --git a/testing/test_functional.py b/testing/test_functional.py --- a/testing/test_functional.py +++ b/testing/test_functional.py @@ -1,23 +1,6 @@ # Copyright 2000-2007 Michael Hudson-Doyle <[email protected]> # Maciek Fijalkowski -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# License: MIT # some functional tests, to see if this is really working import pytest diff --git a/testing/test_readline.py b/testing/test_readline.py new file mode 100644 --- /dev/null +++ b/testing/test_readline.py @@ -0,0 +1,13 @@ +from pyrepl.readline import _ReadlineWrapper +import os, pty + +def test_raw_input(): + readline_wrapper = _ReadlineWrapper() + master, slave = pty.openpty() + readline_wrapper.f_in = slave + os.write(master, 'input\n') + result = readline_wrapper.raw_input('prompt:') + assert result == 'input' + # A bytes string on python2, a unicode string on python3. + assert isinstance(result, str) + diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -14,4 +14,6 @@ event = q.get() assert q.get() is None + assert event.data == a + assert event.raw == b _______________________________________________ pypy-commit mailing list [email protected] http://mail.python.org/mailman/listinfo/pypy-commit
