[Python-checkins] bpo-36982: Add support for extended color functions in ncurses 6.1 (GH-17536)

Hans Petter Jansson webhook-mailer at python.org
Mon Aug 3 23:51:44 EDT 2020


https://github.com/python/cpython/commit/da4e09fff6b483fe858997da5599c25397107ca1
commit: da4e09fff6b483fe858997da5599c25397107ca1
branch: master
author: Hans Petter Jansson <hpj at copyleft.no>
committer: GitHub <noreply at github.com>
date: 2020-08-03T23:51:33-04:00
summary:

bpo-36982: Add support for extended color functions in ncurses 6.1 (GH-17536)

Co-authored-by: Jeffrey Kintscher <websurfer at surf2c.net>

files:
A Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst
M Doc/library/curses.rst
M Doc/whatsnew/3.10.rst
M Lib/test/test_curses.py
M Misc/ACKS
M Modules/_cursesmodule.c
M Modules/clinic/_cursesmodule.c.h

diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index c86ca5d9bc554..0b687db1bd2c4 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -242,6 +242,15 @@ The module :mod:`curses` defines the following functions:
 
    Return ``True`` if the terminal can display colors; otherwise, return ``False``.
 
+.. function:: has_extended_color_support()
+
+   Return ``True`` if the module supports extended colors; otherwise, return
+   ``False``. Extended color support allows more than 256 color pairs for
+   terminals that support more than 16 colors (e.g. xterm-256color).
+
+   Extended color support requires ncurses version 6.1 or later.
+
+   .. versionadded:: 3.10
 
 .. function:: has_ic()
 
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 1865fa227534a..ec0343f2ce71e 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -103,6 +103,16 @@ New Modules
 Improved Modules
 ================
 
+curses
+------
+
+The extended color functions added in ncurses 6.1 will be used transparently
+by :func:`curses.color_content`, :func:`curses.init_color`,
+:func:`curses.init_pair`, and :func:`curses.pair_content`. A new function,
+:func:`curses.has_extended_color_support`, indicates whether extended color
+support is provided by the underlying ncurses library.
+(Contributed by Jeffrey Kintscher and Hans Petter Jansson in :issue:`36982`.)
+
 glob
 ----
 
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index 2c6d14c3f79dd..cabc10da8365c 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -232,7 +232,8 @@ def test_module_funcs(self):
                      curses.nocbreak, curses.noecho, curses.nonl,
                      curses.noqiflush, curses.noraw,
                      curses.reset_prog_mode, curses.termattrs,
-                     curses.termname, curses.erasechar]:
+                     curses.termname, curses.erasechar,
+                     curses.has_extended_color_support]:
             with self.subTest(func=func.__qualname__):
                 func()
         if hasattr(curses, 'filter'):
@@ -293,6 +294,19 @@ def test_colors_funcs(self):
         if hasattr(curses, 'use_default_colors'):
             curses.use_default_colors()
 
+        self.assertRaises(ValueError, curses.color_content, -1)
+        self.assertRaises(ValueError, curses.color_content, curses.COLORS + 1)
+        self.assertRaises(ValueError, curses.color_content, -2**31 - 1)
+        self.assertRaises(ValueError, curses.color_content, 2**31)
+        self.assertRaises(ValueError, curses.color_content, -2**63 - 1)
+        self.assertRaises(ValueError, curses.color_content, 2**63 - 1)
+        self.assertRaises(ValueError, curses.pair_content, -1)
+        self.assertRaises(ValueError, curses.pair_content, curses.COLOR_PAIRS)
+        self.assertRaises(ValueError, curses.pair_content, -2**31 - 1)
+        self.assertRaises(ValueError, curses.pair_content, 2**31)
+        self.assertRaises(ValueError, curses.pair_content, -2**63 - 1)
+        self.assertRaises(ValueError, curses.pair_content, 2**63 - 1)
+
     @requires_curses_func('keyname')
     def test_keyname(self):
         curses.keyname(13)
diff --git a/Misc/ACKS b/Misc/ACKS
index f5e9459276c86..1599b09c692b7 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -798,6 +798,7 @@ Geert Jansen
 Jack Jansen
 Hans-Peter Jansen
 Bill Janssen
+Hans Petter Jansson
 Jon Janzen
 Thomas Jarosch
 Juhana Jauhiainen
@@ -882,6 +883,7 @@ Sam Kimbrel
 Tomohiko Kinebuchi
 James King
 W. Trevor King
+Jeffrey Kintscher
 Paul Kippes
 Steve Kirsch
 Sebastian Kirsche
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst
new file mode 100644
index 0000000000000..f105f1857d487
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst	
@@ -0,0 +1 @@
+Use ncurses extended color functions when available to support terminals with 256 colors, and add the new function :func:`curses.has_extended_color_support` to indicate whether extended color support is provided by the underlying ncurses library.
\ No newline at end of file
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index c70b0e2a19fad..34331017f85c7 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -134,6 +134,31 @@ typedef chtype attr_t;           /* No attr_t type is available */
 #define STRICT_SYSV_CURSES
 #endif
 
+#if defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS)
+#define _NCURSES_EXTENDED_COLOR_FUNCS   1
+#else
+#define _NCURSES_EXTENDED_COLOR_FUNCS   0
+#endif  /* defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS)  */
+
+#if _NCURSES_EXTENDED_COLOR_FUNCS
+#define _NCURSES_COLOR_VAL_TYPE         int
+#define _CURSES_INIT_COLOR_FUNC         init_extended_color
+#define _CURSES_INIT_PAIR_FUNC          init_extended_pair
+#define _COLOR_CONTENT_FUNC             extended_color_content
+#define _CURSES_PAIR_NUMBER_FUNC        extended_pair_content
+#else
+#define _NCURSES_COLOR_VAL_TYPE         short
+#define _CURSES_INIT_COLOR_FUNC         init_color
+#define _CURSES_INIT_PAIR_FUNC          init_pair
+#define _COLOR_CONTENT_FUNC             color_content
+#define _CURSES_PAIR_NUMBER_FUNC        pair_content
+#endif  /* _NCURSES_EXTENDED_COLOR_FUNCS */
+
+#define _CURSES_FUNC_NAME_STR(s)        #s
+
+#define _CURSES_INIT_COLOR_FUNC_NAME    _CURSES_FUNC_NAME_STR(_CURSES_INIT_COLOR_FUNC)
+#define _CURSES_INIT_PAIR_FUNC_NAME     _CURSES_FUNC_NAME_STR(_CURSES_INIT_PAIR_FUNC)
+
 /*[clinic input]
 module _curses
 class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type"
@@ -387,6 +412,104 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
     return 0;
 }
 
+static int
+color_converter(PyObject *arg, void *ptr)
+{
+    long color_number;
+    int overflow;
+
+    color_number = PyLong_AsLongAndOverflow(arg, &overflow);
+    if (color_number == -1 && PyErr_Occurred())
+        return 0;
+
+    if (overflow > 0 || color_number > COLORS) {
+        PyErr_Format(PyExc_ValueError,
+                     "Color number is greater than COLORS (%d).",
+                     COLORS);
+        return 0;
+    }
+    else if (overflow < 0 || color_number < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Color number is less than 0.");
+        return 0;
+    }
+
+    *(int *)ptr = (int)color_number;
+    return 1;
+}
+
+/*[python input]
+class color_converter(CConverter):
+    type = 'int'
+    converter = 'color_converter'
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=4260d2b6e66b3709]*/
+
+static int
+pair_converter(PyObject *arg, void *ptr)
+{
+    long pair_number;
+    int overflow;
+
+    pair_number = PyLong_AsLongAndOverflow(arg, &overflow);
+    if (pair_number == -1 && PyErr_Occurred())
+        return 0;
+
+    if (overflow > 0 || pair_number > COLOR_PAIRS - 1) {
+        PyErr_Format(PyExc_ValueError,
+                     "Color pair is greater than COLOR_PAIRS-1 (%d).",
+                     COLOR_PAIRS - 1);
+        return 0;
+    }
+    else if (overflow < 0 || pair_number < 1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Color pair is less than 1.");
+        return 0;
+    }
+
+    *(int *)ptr = (int)pair_number;
+    return 1;
+}
+
+/*[python input]
+class pair_converter(CConverter):
+    type = 'int'
+    converter = 'pair_converter'
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=1a918ae6a1b32af7]*/
+
+static int
+component_converter(PyObject *arg, void *ptr)
+{
+    long component;
+    int overflow;
+
+    component = PyLong_AsLongAndOverflow(arg, &overflow);
+    if (component == -1 && PyErr_Occurred())
+        return 0;
+
+    if (overflow > 0 || component > 1000) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Color component is greater than 1000");
+        return 0;
+    }
+    else if (overflow < 0 || component < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Color component is less than 0");
+        return 0;
+    }
+
+    *(short *)ptr = (short)component;
+    return 1;
+}
+
+/*[python input]
+class component_converter(CConverter):
+    type = 'short'
+    converter = 'component_converter'
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=38e9be01d33927fb]*/
+
 /* Function versions of the 3 functions for testing whether curses has been
    initialised or not. */
 
@@ -2585,7 +2708,7 @@ NoArgOrFlagNoReturnFunctionBody(cbreak, flag)
 /*[clinic input]
 _curses.color_content
 
-    color_number: short
+    color_number: color
         The number of the color (0 - COLORS).
     /
 
@@ -2596,15 +2719,15 @@ which will be between 0 (no component) and 1000 (maximum amount of component).
 [clinic start generated code]*/
 
 static PyObject *
-_curses_color_content_impl(PyObject *module, short color_number)
-/*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/
+_curses_color_content_impl(PyObject *module, int color_number)
+/*[clinic end generated code: output=17b466df7054e0de input=c10ef58f694b13ee]*/
 {
-    short r,g,b;
+    _NCURSES_COLOR_VAL_TYPE r,g,b;
 
     PyCursesInitialised;
     PyCursesInitialisedColor;
 
-    if (color_content(color_number, &r, &g, &b) != ERR)
+    if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) != ERR)
         return Py_BuildValue("(iii)", r, g, b);
     else {
         PyErr_SetString(PyCursesError,
@@ -2616,7 +2739,7 @@ _curses_color_content_impl(PyObject *module, short color_number)
 /*[clinic input]
 _curses.color_pair
 
-    color_number: short
+    color_number: color
         The number of the color (0 - COLORS).
     /
 
@@ -2627,8 +2750,8 @@ other A_* attributes.  pair_number() is the counterpart to this function.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_color_pair_impl(PyObject *module, short color_number)
-/*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/
+_curses_color_pair_impl(PyObject *module, int color_number)
+/*[clinic end generated code: output=3fd752e8e24c93fb input=b049033819ab4ef5]*/
 {
     PyCursesInitialised;
     PyCursesInitialisedColor;
@@ -3027,13 +3150,13 @@ _curses_has_key_impl(PyObject *module, int key)
 /*[clinic input]
 _curses.init_color
 
-    color_number: short
+    color_number: color
         The number of the color to be changed (0 - COLORS).
-    r: short
+    r: component
         Red component (0 - 1000).
-    g: short
+    g: component
         Green component (0 - 1000).
-    b: short
+    b: component
         Blue component (0 - 1000).
     /
 
@@ -3045,24 +3168,24 @@ most terminals; it is active only if can_change_color() returns 1.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_init_color_impl(PyObject *module, short color_number, short r,
-                        short g, short b)
-/*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/
+_curses_init_color_impl(PyObject *module, int color_number, short r, short g,
+                        short b)
+/*[clinic end generated code: output=d7ed71b2d818cdf2 input=8a2fe94ca9204aa5]*/
 {
     PyCursesInitialised;
     PyCursesInitialisedColor;
 
-    return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color");
+    return PyCursesCheckERR(_CURSES_INIT_COLOR_FUNC(color_number, r, g, b), _CURSES_INIT_COLOR_FUNC_NAME);
 }
 
 /*[clinic input]
 _curses.init_pair
 
-    pair_number: short
+    pair_number: pair
         The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).
-    fg: short
+    fg: color
         Foreground color number (0 - COLORS).
-    bg: short
+    bg: color
         Background color number (0 - COLORS).
     /
 
@@ -3073,14 +3196,13 @@ all occurrences of that color-pair are changed to the new definition.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_init_pair_impl(PyObject *module, short pair_number, short fg,
-                       short bg)
-/*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/
+_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg)
+/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=b865583a18061c1f]*/
 {
     PyCursesInitialised;
     PyCursesInitialisedColor;
 
-    return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair");
+    return PyCursesCheckERR(_CURSES_INIT_PAIR_FUNC(pair_number, fg, bg), _CURSES_INIT_PAIR_FUNC_NAME);
 }
 
 static PyObject *ModDict;
@@ -3697,7 +3819,7 @@ NoArgNoReturnFunctionBody(noraw)
 /*[clinic input]
 _curses.pair_content
 
-    pair_number: short
+    pair_number: pair
         The number of the color pair (1 - (COLOR_PAIRS-1)).
     /
 
@@ -3705,15 +3827,15 @@ Return a tuple (fg, bg) containing the colors for the requested color pair.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_pair_content_impl(PyObject *module, short pair_number)
-/*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/
+_curses_pair_content_impl(PyObject *module, int pair_number)
+/*[clinic end generated code: output=4a726dd0e6885f3f input=b42eacf8a4103852]*/
 {
-    short f, b;
+    _NCURSES_COLOR_VAL_TYPE f, b;
 
     PyCursesInitialised;
     PyCursesInitialisedColor;
 
-    if (pair_content(pair_number, &f, &b)==ERR) {
+    if (_CURSES_PAIR_NUMBER_FUNC(pair_number, &f, &b)==ERR) {
         PyErr_SetString(PyCursesError,
                         "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
         return NULL;
@@ -4450,6 +4572,21 @@ make_ncurses_version(void)
 
 #endif /* NCURSES_VERSION */
 
+/*[clinic input]
+_curses.has_extended_color_support
+
+Return True if the module supports extended colors; otherwise, return False.
+
+Extended color support allows more than 256 color-pairs for terminals
+that support more than 16 colors (e.g. xterm-256color).
+[clinic start generated code]*/
+
+static PyObject *
+_curses_has_extended_color_support_impl(PyObject *module)
+/*[clinic end generated code: output=68f1be2b57d92e22 input=4b905f046e35ee9f]*/
+{
+    return PyBool_FromLong(_NCURSES_EXTENDED_COLOR_FUNCS);
+}
 
 /* List of functions defined in the module */
 
@@ -4476,6 +4613,7 @@ static PyMethodDef PyCurses_methods[] = {
     _CURSES_GETSYX_METHODDEF
     _CURSES_GETWIN_METHODDEF
     _CURSES_HAS_COLORS_METHODDEF
+    _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF
     _CURSES_HAS_IC_METHODDEF
     _CURSES_HAS_IL_METHODDEF
     _CURSES_HAS_KEY_METHODDEF
diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h
index f686ded51976c..c4c2b71e4cc22 100644
--- a/Modules/clinic/_cursesmodule.c.h
+++ b/Modules/clinic/_cursesmodule.c.h
@@ -1967,32 +1967,16 @@ PyDoc_STRVAR(_curses_color_content__doc__,
     {"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__},
 
 static PyObject *
-_curses_color_content_impl(PyObject *module, short color_number);
+_curses_color_content_impl(PyObject *module, int color_number);
 
 static PyObject *
 _curses_color_content(PyObject *module, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    short color_number;
+    int color_number;
 
-    {
-        long ival = PyLong_AsLong(arg);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            color_number = (short) ival;
-        }
+    if (!color_converter(arg, &color_number)) {
+        goto exit;
     }
     return_value = _curses_color_content_impl(module, color_number);
 
@@ -2016,32 +2000,16 @@ PyDoc_STRVAR(_curses_color_pair__doc__,
     {"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__},
 
 static PyObject *
-_curses_color_pair_impl(PyObject *module, short color_number);
+_curses_color_pair_impl(PyObject *module, int color_number);
 
 static PyObject *
 _curses_color_pair(PyObject *module, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    short color_number;
+    int color_number;
 
-    {
-        long ival = PyLong_AsLong(arg);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            color_number = (short) ival;
-        }
+    if (!color_converter(arg, &color_number)) {
+        goto exit;
     }
     return_value = _curses_color_pair_impl(module, color_number);
 
@@ -2590,14 +2558,14 @@ PyDoc_STRVAR(_curses_init_color__doc__,
     {"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__},
 
 static PyObject *
-_curses_init_color_impl(PyObject *module, short color_number, short r,
-                        short g, short b);
+_curses_init_color_impl(PyObject *module, int color_number, short r, short g,
+                        short b);
 
 static PyObject *
 _curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
-    short color_number;
+    int color_number;
     short r;
     short g;
     short b;
@@ -2605,81 +2573,17 @@ _curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("init_color", nargs, 4, 4)) {
         goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[0]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            color_number = (short) ival;
-        }
+    if (!color_converter(args[0], &color_number)) {
+        goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[1]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            r = (short) ival;
-        }
+    if (!component_converter(args[1], &r)) {
+        goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[2]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            g = (short) ival;
-        }
+    if (!component_converter(args[2], &g)) {
+        goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[3]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            b = (short) ival;
-        }
+    if (!component_converter(args[3], &b)) {
+        goto exit;
     }
     return_value = _curses_init_color_impl(module, color_number, r, g, b);
 
@@ -2707,76 +2611,27 @@ PyDoc_STRVAR(_curses_init_pair__doc__,
     {"init_pair", (PyCFunction)(void(*)(void))_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__},
 
 static PyObject *
-_curses_init_pair_impl(PyObject *module, short pair_number, short fg,
-                       short bg);
+_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg);
 
 static PyObject *
 _curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
-    short pair_number;
-    short fg;
-    short bg;
+    int pair_number;
+    int fg;
+    int bg;
 
     if (!_PyArg_CheckPositional("init_pair", nargs, 3, 3)) {
         goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[0]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            pair_number = (short) ival;
-        }
+    if (!pair_converter(args[0], &pair_number)) {
+        goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[1]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            fg = (short) ival;
-        }
+    if (!color_converter(args[1], &fg)) {
+        goto exit;
     }
-    {
-        long ival = PyLong_AsLong(args[2]);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            bg = (short) ival;
-        }
+    if (!color_converter(args[2], &bg)) {
+        goto exit;
     }
     return_value = _curses_init_pair_impl(module, pair_number, fg, bg);
 
@@ -3554,32 +3409,16 @@ PyDoc_STRVAR(_curses_pair_content__doc__,
     {"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__},
 
 static PyObject *
-_curses_pair_content_impl(PyObject *module, short pair_number);
+_curses_pair_content_impl(PyObject *module, int pair_number);
 
 static PyObject *
 _curses_pair_content(PyObject *module, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    short pair_number;
+    int pair_number;
 
-    {
-        long ival = PyLong_AsLong(arg);
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        else if (ival < SHRT_MIN) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is less than minimum");
-            goto exit;
-        }
-        else if (ival > SHRT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "signed short integer is greater than maximum");
-            goto exit;
-        }
-        else {
-            pair_number = (short) ival;
-        }
+    if (!pair_converter(arg, &pair_number)) {
+        goto exit;
     }
     return_value = _curses_pair_content_impl(module, pair_number);
 
@@ -4337,6 +4176,27 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored))
 
 #endif /* !defined(STRICT_SYSV_CURSES) */
 
+PyDoc_STRVAR(_curses_has_extended_color_support__doc__,
+"has_extended_color_support($module, /)\n"
+"--\n"
+"\n"
+"Return True if the module supports extended colors; otherwise, return False.\n"
+"\n"
+"Extended color support allows more than 256 color-pairs for terminals\n"
+"that support more than 16 colors (e.g. xterm-256color).");
+
+#define _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF    \
+    {"has_extended_color_support", (PyCFunction)_curses_has_extended_color_support, METH_NOARGS, _curses_has_extended_color_support__doc__},
+
+static PyObject *
+_curses_has_extended_color_support_impl(PyObject *module);
+
+static PyObject *
+_curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return _curses_has_extended_color_support_impl(module);
+}
+
 #ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF
     #define _CURSES_WINDOW_ENCLOSE_METHODDEF
 #endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */
@@ -4428,4 +4288,4 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored))
 #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF
     #define _CURSES_USE_DEFAULT_COLORS_METHODDEF
 #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=478d93f7692385eb input=a9049054013a1b77]*/
+/*[clinic end generated code: output=38b2531d17f119e1 input=a9049054013a1b77]*/



More information about the Python-checkins mailing list