]> granicus.if.org Git - python/commitdiff
Issue #12567: Add curses.unget_wch() function
authorVictor Stinner <victor.stinner@haypocalc.com>
Mon, 5 Sep 2011 23:53:03 +0000 (01:53 +0200)
committerVictor Stinner <victor.stinner@haypocalc.com>
Mon, 5 Sep 2011 23:53:03 +0000 (01:53 +0200)
Push a character so the next get_wch() will return it.

Doc/library/curses.rst
Lib/test/test_curses.py
Misc/NEWS
Modules/_cursesmodule.c

index f27b2ff1c098553ab7e59e7c1f848bf68f08109c..df259109c6f9dff6db6349d465459e001c10a239 100644 (file)
@@ -598,6 +598,17 @@ The module :mod:`curses` defines the following functions:
       Only one *ch* can be pushed before :meth:`getch` is called.
 
 
+.. function:: unget_wch(ch)
+
+   Push *ch* so the next :meth:`get_wch` will return it.
+
+   .. note::
+
+      Only one *ch* can be pushed before :meth:`get_wch` is called.
+
+   .. versionadded:: 3.3
+
+
 .. function:: ungetmouse(id, x, y, z, bstate)
 
    Push a :const:`KEY_MOUSE` event onto the input queue, associating the given
index c767e9388f62f509b99cc68f9fa745e0ce308cdd..8caf0deaef0bca7379277b10e634f6ca50cc598c 100644 (file)
@@ -264,6 +264,20 @@ def test_issue6243(stdscr):
     curses.ungetch(1025)
     stdscr.getkey()
 
+def test_unget_wch(stdscr):
+    ch = '\xe9'
+    curses.unget_wch(ch)
+    read = stdscr.get_wch()
+    read = chr(read)
+    if read != ch:
+        raise AssertionError("%r != %r" % (read, ch))
+
+    ch = ord('\xe9')
+    curses.unget_wch(ch)
+    read = stdscr.get_wch()
+    if read != ch:
+        raise AssertionError("%r != %r" % (read, ch))
+
 def main(stdscr):
     curses.savetty()
     try:
@@ -272,6 +286,7 @@ def main(stdscr):
         test_userptr_without_set(stdscr)
         test_resize_term(stdscr)
         test_issue6243(stdscr)
+        test_unget_wch(stdscr)
     finally:
         curses.resetty()
 
index fbcdb8d1989e11088e6bb0cb793fdc218a2a7b46..85af2acf3e728780d4fbd7e2c01a37f51f9f71ae 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -271,6 +271,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #12567: Add curses.unget_wch() function. Push a character so the next
+  get_wch() will return it.
+
 - Issue #9561: distutils and packaging now writes egg-info files using UTF-8,
   instead of the locale encoding.
 
index 6d720245a72e136ca7c9e78629ebb2c845689516..ef0a66c0ede99f3c0926813ff87bed8cdc3fdf5f 100644 (file)
@@ -2696,6 +2696,71 @@ PyCurses_UngetCh(PyObject *self, PyObject *args)
     return PyCursesCheckERR(ungetch(ch), "ungetch");
 }
 
+#ifdef HAVE_NCURSESW
+/* Convert an object to a character (wchar_t):
+
+    - int
+    - str of length 1
+
+   Return 1 on success, 0 on error. */
+static int
+PyCurses_ConvertToWchar_t(PyObject *obj,
+                          wchar_t *wch)
+{
+    if (PyUnicode_Check(obj)) {
+        wchar_t buffer[2];
+        if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
+            PyErr_Format(PyExc_TypeError,
+                         "expect bytes or str of length 1, or int, "
+                         "got a str of length %zi",
+                         PyUnicode_GET_SIZE(obj));
+            return 0;
+        }
+        *wch = buffer[0];
+        return 2;
+    }
+    else if (PyLong_CheckExact(obj)) {
+        long value;
+        int overflow;
+        value = PyLong_AsLongAndOverflow(obj, &overflow);
+        if (overflow) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "int doesn't fit in long");
+            return 0;
+        }
+        *wch = (wchar_t)value;
+        if ((long)*wch != value) {
+            PyErr_Format(PyExc_OverflowError,
+                         "character doesn't fit in wchar_t");
+            return 0;
+        }
+        return 1;
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "expect bytes or str of length 1, or int, got %s",
+                     Py_TYPE(obj)->tp_name);
+        return 0;
+    }
+}
+
+static PyObject *
+PyCurses_Unget_Wch(PyObject *self, PyObject *args)
+{
+    PyObject *obj;
+    wchar_t wch;
+
+    PyCursesInitialised;
+
+    if (!PyArg_ParseTuple(args,"O", &obj))
+        return NULL;
+
+    if (!PyCurses_ConvertToWchar_t(obj, &wch))
+        return NULL;
+    return PyCursesCheckERR(unget_wch(wch), "unget_wch");
+}
+#endif
+
 static PyObject *
 PyCurses_Use_Env(PyObject *self, PyObject *args)
 {
@@ -2823,6 +2888,9 @@ static PyMethodDef PyCurses_methods[] = {
     {"typeahead",           (PyCFunction)PyCurses_TypeAhead, METH_VARARGS},
     {"unctrl",              (PyCFunction)PyCurses_UnCtrl, METH_VARARGS},
     {"ungetch",             (PyCFunction)PyCurses_UngetCh, METH_VARARGS},
+#ifdef HAVE_NCURSESW
+    {"unget_wch",           (PyCFunction)PyCurses_Unget_Wch, METH_VARARGS},
+#endif
     {"use_env",             (PyCFunction)PyCurses_Use_Env, METH_VARARGS},
 #ifndef STRICT_SYSV_CURSES
     {"use_default_colors",  (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS},