https://github.com/python/cpython/commit/ee36db550076e5a9185444ffbc53eaf8157ef04c
commit: ee36db550076e5a9185444ffbc53eaf8157ef04c
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-05-19T15:53:39+02:00
summary:

gh-125843: indicate which C function caused a `curses.error` (#125844)

- Rename error helpers with a `curses_set_error_*` prefix instead of 
`PyCurses*`.
- Cleanly report both NULL and ERR cases.
- Raise `curses.error` in `is_linetouched` instead of a `TypeError`.

files:
A Misc/NEWS.d/next/Library/2024-10-22-16-21-55.gh-issue-125843.2ttzYo.rst
M Include/py_curses.h
M Lib/test/test_curses.py
M Modules/_cursesmodule.c

diff --git a/Include/py_curses.h b/Include/py_curses.h
index 49fc3c9d127aa6..0948aabedd4993 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -109,6 +109,13 @@ static void **PyCurses_API;
 static const char catchall_ERR[]  = "curses function returned ERR";
 static const char catchall_NULL[] = "curses function returned NULL";
 
+#if defined(CURSES_MODULE) || defined(CURSES_PANEL_MODULE)
+/* Error messages shared by the curses package */
+#  define CURSES_ERROR_FORMAT           "%s() returned %s"
+#  define CURSES_ERROR_VERBOSE_FORMAT   "%s() (called by %s()) returned %s"
+#  define CURSES_ERROR_MUST_CALL_FORMAT "must call %s() first"
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index c307258e5657e2..feca82681deb7c 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -130,6 +130,9 @@ def test_use_env(self):
         curses.use_env(False)
         curses.use_env(True)
 
+    def test_error(self):
+        self.assertIsSubclass(curses.error, Exception)
+
     def test_create_windows(self):
         win = curses.newwin(5, 10)
         self.assertEqual(win.getbegyx(), (0, 0))
diff --git 
a/Misc/NEWS.d/next/Library/2024-10-22-16-21-55.gh-issue-125843.2ttzYo.rst 
b/Misc/NEWS.d/next/Library/2024-10-22-16-21-55.gh-issue-125843.2ttzYo.rst
new file mode 100644
index 00000000000000..ec8f3a750065ff
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-22-16-21-55.gh-issue-125843.2ttzYo.rst
@@ -0,0 +1,2 @@
+If possible, indicate which :mod:`curses` C function or macro is responsible
+for raising a :exc:`curses.error` exception. Patch by Bénédikt Tran.
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index cd185bc2b02ea5..ab63fdbe45de61 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -211,18 +211,116 @@ static int curses_start_color_called = FALSE;
 
 static const char *curses_screen_encoding = NULL;
 
+/* Utility Error Procedures */
+
+static void
+_curses_format_error(cursesmodule_state *state,
+                     const char *curses_funcname,
+                     const char *python_funcname,
+                     const char *return_value,
+                     const char *default_message)
+{
+    assert(!PyErr_Occurred());
+    if (python_funcname == NULL && curses_funcname == NULL) {
+        PyErr_SetString(state->error, default_message);
+    }
+    else if (python_funcname == NULL) {
+        (void)PyErr_Format(state->error, CURSES_ERROR_FORMAT,
+                           curses_funcname, return_value);
+    }
+    else {
+        assert(python_funcname != NULL);
+        (void)PyErr_Format(state->error, CURSES_ERROR_VERBOSE_FORMAT,
+                           curses_funcname, python_funcname, return_value);
+    }
+}
+
+/*
+ * Format a curses error for a function that returned ERR.
+ *
+ * Specify a non-NULL 'python_funcname' when the latter differs from
+ * 'curses_funcname'. If both names are NULL, uses the 'catchall_ERR'
+ * message instead.
+ */
+static void
+_curses_set_error(cursesmodule_state *state,
+                  const char *curses_funcname,
+                  const char *python_funcname)
+{
+    _curses_format_error(state, curses_funcname, python_funcname,
+                         "ERR", catchall_ERR);
+}
+
+/*
+ * Format a curses error for a function that returned NULL.
+ *
+ * Specify a non-NULL 'python_funcname' when the latter differs from
+ * 'curses_funcname'. If both names are NULL, uses the 'catchall_NULL'
+ * message instead.
+ */
+static inline void
+_curses_set_null_error(cursesmodule_state *state,
+                       const char *curses_funcname,
+                       const char *python_funcname)
+{
+    _curses_format_error(state, curses_funcname, python_funcname,
+                         "NULL", catchall_NULL);
+}
+
+/* Same as _curses_set_error() for a module object. */
+static void
+curses_set_error(PyObject *module,
+                 const char *curses_funcname,
+                 const char *python_funcname)
+{
+    cursesmodule_state *state = get_cursesmodule_state(module);
+    _curses_set_error(state, curses_funcname, python_funcname);
+}
+
+/* Same as _curses_set_null_error() for a module object. */
+static void
+curses_set_null_error(PyObject *module,
+                      const char *curses_funcname,
+                      const char *python_funcname)
+{
+    cursesmodule_state *state = get_cursesmodule_state(module);
+    _curses_set_null_error(state, curses_funcname, python_funcname);
+}
+
+/* Same as _curses_set_error() for a Window object. */
+static void
+curses_window_set_error(PyCursesWindowObject *win,
+                        const char *curses_funcname,
+                        const char *python_funcname)
+{
+    cursesmodule_state *state = get_cursesmodule_state_by_win(win);
+    _curses_set_error(state, curses_funcname, python_funcname);
+}
+
+/* Same as _curses_set_null_error() for a Window object. */
+static void
+curses_window_set_null_error(PyCursesWindowObject *win,
+                             const char *curses_funcname,
+                             const char *python_funcname)
+{
+    cursesmodule_state *state = get_cursesmodule_state_by_win(win);
+    _curses_set_null_error(state, curses_funcname, python_funcname);
+}
+
 /* Utility Checking Procedures */
 
 /*
  * Function to check that 'funcname' has been called by testing
- * the 'called' boolean. If an error occurs, a PyCursesError is
+ * the 'called' boolean. If an error occurs, an exception is
  * set and this returns 0. Otherwise, this returns 1.
  *
  * Since this function can be called in functions that do not
  * have a direct access to the module's state, '_curses.error'
  * is imported on demand.
+ *
+ * Use _PyCursesStatefulCheckFunction() if the module is given.
  */
-static inline int
+static int
 _PyCursesCheckFunction(int called, const char *funcname)
 {
     if (called == TRUE) {
@@ -230,7 +328,7 @@ _PyCursesCheckFunction(int called, const char *funcname)
     }
     PyObject *exc = PyImport_ImportModuleAttrString("_curses", "error");
     if (exc != NULL) {
-        PyErr_Format(exc, "must call %s() first", funcname);
+        PyErr_Format(exc, CURSES_ERROR_MUST_CALL_FORMAT, funcname);
         Py_DECREF(exc);
     }
     assert(PyErr_Occurred());
@@ -244,14 +342,15 @@ _PyCursesCheckFunction(int called, const char *funcname)
  *
  * The exception type is obtained from the 'module' state.
  */
-static inline int
-_PyCursesStatefulCheckFunction(PyObject *module, int called, const char 
*funcname)
+static int
+_PyCursesStatefulCheckFunction(PyObject *module,
+                               int called, const char *funcname)
 {
     if (called == TRUE) {
         return 1;
     }
     cursesmodule_state *state = get_cursesmodule_state(module);
-    PyErr_Format(state->error, "must call %s() first", funcname);
+    PyErr_Format(state->error, CURSES_ERROR_MUST_CALL_FORMAT, funcname);
     return 0;
 }
 
@@ -287,44 +386,41 @@ _PyCursesStatefulCheckFunction(PyObject *module, int 
called, const char *funcnam
 
 /* Utility Functions */
 
-static inline void
-_PyCursesSetError(cursesmodule_state *state, const char *funcname)
-{
-    if (funcname == NULL) {
-        PyErr_SetString(state->error, catchall_ERR);
-    }
-    else {
-        PyErr_Format(state->error, "%s() returned ERR", funcname);
-    }
-}
-
 /*
- * Check the return code from a curses function and return None
- * or raise an exception as appropriate.
+ * Check the return code from a curses function, returning None
+ * on success and setting an exception on error.
  */
 
+/*
+ * Return None if 'code' is OK. Otherwise, set an exception
+ * using curses_set_error() and the remaining arguments, and
+ * return NULL.
+ */
 static PyObject *
-PyCursesCheckERR(PyObject *module, int code, const char *fname)
+curses_check_err(PyObject *module, int code,
+                 const char *curses_funcname,
+                 const char *python_funcname)
 {
     if (code != ERR) {
+        assert(code == OK);
         Py_RETURN_NONE;
-    } else {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        _PyCursesSetError(state, fname);
-        return NULL;
     }
+    curses_set_error(module, curses_funcname, python_funcname);
+    return NULL;
 }
 
+/* Same as curses_check_err() for a Window object. */
 static PyObject *
-PyCursesCheckERR_ForWin(PyCursesWindowObject *win, int code, const char *fname)
+curses_window_check_err(PyCursesWindowObject *win, int code,
+                        const char *curses_funcname,
+                        const char *python_funcname)
 {
     if (code != ERR) {
+        assert(code == OK);
         Py_RETURN_NONE;
-    } else {
-        cursesmodule_state *state = get_cursesmodule_state_by_win(win);
-        _PyCursesSetError(state, fname);
-        return NULL;
     }
+    curses_window_set_error(win, curses_funcname, python_funcname);
+    return NULL;
 }
 
 /* Convert an object to a byte (an integer of type chtype):
@@ -650,13 +746,16 @@ class component_converter(CConverter):
  The Window Object
 ******************************************************************************/
 
-/* Function prototype macros for Window object
-
-   X - function name
-   TYPE - parameter Type
-   ERGSTR - format string for construction of the return value
-   PARSESTR - format string for argument parsing
-*/
+/*
+ * Macros for creating a PyCursesWindowObject object's method.
+ *
+ * Parameters
+ *
+ *  X           The name of the curses C function or macro to invoke.
+ *  TYPE        The function parameter(s) type.
+ *  ERGSTR      The format string for construction of the return value.
+ *  PARSESTR    The format string for argument parsing.
+ */
 
 #define Window_NoArgNoReturnFunction(X)                                 \
     static PyObject *PyCursesWindow_ ## X                               \
@@ -664,7 +763,7 @@ class component_converter(CConverter):
     {                                                                   \
         PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op);    \
         int code = X(self->win);                                        \
-        return PyCursesCheckERR_ForWin(self, code, # X);                \
+        return curses_window_check_err(self, code, # X, NULL);          \
     }
 
 #define Window_NoArgTrueFalseFunction(X)                                \
@@ -717,7 +816,7 @@ class component_converter(CConverter):
         }                                                               \
         PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op);    \
         int code = X(self->win, arg1);                                  \
-        return PyCursesCheckERR_ForWin(self, code, # X);                \
+        return curses_window_check_err(self, code, # X, NULL);          \
     }
 
 #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR)                \
@@ -730,7 +829,7 @@ class component_converter(CConverter):
         }                                                               \
         PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op);    \
         int code = X(self->win, arg1, arg2);                            \
-        return PyCursesCheckERR_ForWin(self, code, # X);                \
+        return curses_window_check_err(self, code, # X, NULL);          \
     }
 
 /* ------------- WINDOW routines --------------- */
@@ -903,13 +1002,15 @@ _curses_window_addch_impl(PyCursesWindowObject *self, 
int group_left_1,
 #ifdef HAVE_NCURSESW
     type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr);
     if (type == 2) {
-        funcname = "add_wch";
         wstr[1] = L'\0';
         setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL);
-        if (coordinates_group)
+        if (coordinates_group) {
             rtn = mvwadd_wch(self->win,y,x, &wcval);
+            funcname = "mvwadd_wch";
+        }
         else {
             rtn = wadd_wch(self->win, &wcval);
+            funcname = "wadd_wch";
         }
     }
     else
@@ -917,17 +1018,19 @@ _curses_window_addch_impl(PyCursesWindowObject *self, 
int group_left_1,
     type = PyCurses_ConvertToCchar_t(self, ch, &cch);
 #endif
     if (type == 1) {
-        funcname = "addch";
-        if (coordinates_group)
+        if (coordinates_group) {
             rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr);
+            funcname = "mvwaddch";
+        }
         else {
             rtn = waddch(self->win, cch | (attr_t) attr);
+            funcname = "waddch";
         }
     }
     else {
         return NULL;
     }
-    return PyCursesCheckERR_ForWin(self, rtn, funcname);
+    return curses_window_check_err(self, rtn, funcname, "addch");
 }
 
 /*[clinic input]
@@ -987,27 +1090,33 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, 
int group_left_1,
     }
 #ifdef HAVE_NCURSESW
     if (strtype == 2) {
-        funcname = "addwstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwaddwstr(self->win,y,x,wstr);
-        else
+            funcname = "mvwaddwstr";
+        }
+        else {
             rtn = waddwstr(self->win,wstr);
+            funcname = "waddwstr";
+        }
         PyMem_Free(wstr);
     }
     else
 #endif
     {
         const char *str = PyBytes_AS_STRING(bytesobj);
-        funcname = "addstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwaddstr(self->win,y,x,str);
-        else
+            funcname = "mvwaddstr";
+        }
+        else {
             rtn = waddstr(self->win,str);
+            funcname = "waddstr";
+        }
         Py_DECREF(bytesobj);
     }
     if (use_attr)
         (void)wattrset(self->win,attr_old);
-    return PyCursesCheckERR_ForWin(self, rtn, funcname);
+    return curses_window_check_err(self, rtn, funcname, "addstr");
 }
 
 /*[clinic input]
@@ -1070,27 +1179,33 @@ _curses_window_addnstr_impl(PyCursesWindowObject *self, 
int group_left_1,
     }
 #ifdef HAVE_NCURSESW
     if (strtype == 2) {
-        funcname = "addnwstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwaddnwstr(self->win,y,x,wstr,n);
-        else
+            funcname = "mvwaddnwstr";
+        }
+        else {
             rtn = waddnwstr(self->win,wstr,n);
+            funcname = "waddnwstr";
+        }
         PyMem_Free(wstr);
     }
     else
 #endif
     {
         const char *str = PyBytes_AS_STRING(bytesobj);
-        funcname = "addnstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwaddnstr(self->win,y,x,str,n);
-        else
+            funcname = "mvwaddnstr";
+        }
+        else {
             rtn = waddnstr(self->win,str,n);
+            funcname = "waddnstr";
+        }
         Py_DECREF(bytesobj);
     }
     if (use_attr)
         (void)wattrset(self->win,attr_old);
-    return PyCursesCheckERR_ForWin(self, rtn, funcname);
+    return curses_window_check_err(self, rtn, funcname, "addnstr");
 }
 
 /*[clinic input]
@@ -1114,7 +1229,8 @@ _curses_window_bkgd_impl(PyCursesWindowObject *self, 
PyObject *ch, long attr)
     if (!PyCurses_ConvertToChtype(self, ch, &bkgd))
         return NULL;
 
-    return PyCursesCheckERR_ForWin(self, wbkgd(self->win, bkgd | attr), 
"bkgd");
+    int rtn = wbkgd(self->win, bkgd | attr);
+    return curses_window_check_err(self, rtn, "wbkgd", "bkgd");
 }
 
 /*[clinic input]
@@ -1130,7 +1246,8 @@ static PyObject *
 _curses_window_attroff_impl(PyCursesWindowObject *self, long attr)
 /*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/
 {
-    return PyCursesCheckERR_ForWin(self, wattroff(self->win, (attr_t)attr), 
"attroff");
+    int rtn = wattroff(self->win, (attr_t)attr);
+    return curses_window_check_err(self, rtn, "wattroff", "attroff");
 }
 
 /*[clinic input]
@@ -1146,7 +1263,8 @@ static PyObject *
 _curses_window_attron_impl(PyCursesWindowObject *self, long attr)
 /*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/
 {
-    return PyCursesCheckERR_ForWin(self, wattron(self->win, (attr_t)attr), 
"attron");
+    int rtn = wattron(self->win, (attr_t)attr);
+    return curses_window_check_err(self, rtn, "wattron", "attron");
 }
 
 /*[clinic input]
@@ -1162,7 +1280,8 @@ static PyObject *
 _curses_window_attrset_impl(PyCursesWindowObject *self, long attr)
 /*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/
 {
-    return PyCursesCheckERR_ForWin(self, wattrset(self->win, (attr_t)attr), 
"attrset");
+    int rtn = wattrset(self->win, (attr_t)attr);
+    return curses_window_check_err(self, rtn, "wattrset", "attrset");
 }
 
 /*[clinic input]
@@ -1188,7 +1307,7 @@ _curses_window_bkgdset_impl(PyCursesWindowObject *self, 
PyObject *ch,
         return NULL;
 
     wbkgdset(self->win, bkgd | attr);
-    return PyCursesCheckERR_ForWin(self, 0, "bkgdset");
+    Py_RETURN_NONE;
 }
 
 /*[clinic input]
@@ -1344,6 +1463,7 @@ PyCursesWindow_ChgAt(PyObject *op, PyObject *args)
     PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op);
 
     int rtn;
+    const char *funcname;
     int x, y;
     int num = -1;
     short color;
@@ -1385,12 +1505,14 @@ PyCursesWindow_ChgAt(PyObject *op, PyObject *args)
     if (use_xy) {
         rtn = mvwchgat(self->win,y,x,num,attr,color,NULL);
         touchline(self->win,y,1);
+        funcname = "mvwchgat";
     } else {
         getyx(self->win,y,x);
         rtn = wchgat(self->win,num,attr,color,NULL);
         touchline(self->win,y,1);
+        funcname = "wchgat";
     }
-    return PyCursesCheckERR_ForWin(self, rtn, "chgat");
+    return curses_window_check_err(self, rtn, funcname, "chgat");
 }
 #endif
 
@@ -1413,12 +1535,17 @@ _curses_window_delch_impl(PyCursesWindowObject *self, 
int group_right_1,
                           int y, int x)
 /*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/
 {
+    int rtn;
+    const char *funcname;
     if (!group_right_1) {
-        return PyCursesCheckERR_ForWin(self, wdelch(self->win), "wdelch");
+        rtn = wdelch(self->win);
+        funcname = "wdelch";
     }
     else {
-        return PyCursesCheckERR_ForWin(self, py_mvwdelch(self->win, y, x), 
"mvwdelch");
+        rtn = py_mvwdelch(self->win, y, x);
+        funcname = "mvwdelch";
     }
+    return curses_window_check_err(self, rtn, funcname, "delch");
 }
 
 /*[clinic input]
@@ -1453,8 +1580,7 @@ _curses_window_derwin_impl(PyCursesWindowObject *self, 
int group_left_1,
     win = derwin(self->win,nlines,ncols,begin_y,begin_x);
 
     if (win == NULL) {
-        cursesmodule_state *state = get_cursesmodule_state_by_win(self);
-        PyErr_SetString(state->error, catchall_NULL);
+        curses_window_set_error(self, "derwin", NULL);
         return NULL;
     }
 
@@ -1485,17 +1611,20 @@ _curses_window_echochar_impl(PyCursesWindowObject 
*self, PyObject *ch,
     if (!PyCurses_ConvertToChtype(self, ch, &ch_))
         return NULL;
 
+    int rtn;
+    const char *funcname;
 #ifdef py_is_pad
     if (py_is_pad(self->win)) {
-        return PyCursesCheckERR_ForWin(self,
-                                       pechochar(self->win, ch_ | 
(attr_t)attr),
-                                       "echochar");
+        rtn = pechochar(self->win, ch_ | (attr_t)attr);
+        funcname = "pechochar";
     }
     else
 #endif
-        return PyCursesCheckERR_ForWin(self,
-                                       wechochar(self->win, ch_ | 
(attr_t)attr),
-                                       "echochar");
+    {
+        rtn = wechochar(self->win, ch_ | (attr_t)attr);
+        funcname = "wechochar";
+    }
+    return curses_window_check_err(self, rtn, funcname, "echochar");
 }
 
 #ifdef NCURSES_MOUSE_VERSION
@@ -1608,7 +1737,8 @@ _curses_window_getkey_impl(PyCursesWindowObject *self, 
int group_right_1,
         PyErr_CheckSignals();
         if (!PyErr_Occurred()) {
             cursesmodule_state *state = get_cursesmodule_state_by_win(self);
-            PyErr_SetString(state->error, "no input");
+            const char *funcname = group_right_1 ? "mvwgetch" : "wgetch";
+            PyErr_Format(state->error, "getkey(): %s(): no input", funcname);
         }
         return NULL;
     } else if (rtn <= 255) {
@@ -1668,7 +1798,8 @@ _curses_window_get_wch_impl(PyCursesWindowObject *self, 
int group_right_1,
 
         /* get_wch() returns ERR in nodelay mode */
         cursesmodule_state *state = get_cursesmodule_state_by_win(self);
-        PyErr_SetString(state->error, "no input");
+        const char *funcname = group_right_1 ? "mvwget_wch" : "wget_wch";
+        PyErr_Format(state->error, "get_wch(): %s(): no input", funcname);
         return NULL;
     }
     if (ct == KEY_CODE_YES)
@@ -1794,10 +1925,12 @@ _curses_window_hline_impl(PyCursesWindowObject *self, 
int group_left_1,
         return NULL;
     if (group_left_1) {
         if (wmove(self->win, y, x) == ERR) {
-            return PyCursesCheckERR_ForWin(self, ERR, "wmove");
+            curses_window_set_error(self, "wmove", "hline");
+            return NULL;
         }
     }
-    return PyCursesCheckERR_ForWin(self, whline(self->win, ch_ | (attr_t)attr, 
n), "hline");
+    int rtn = whline(self->win, ch_ | (attr_t)attr, n);
+    return curses_window_check_err(self, rtn, "whline", "hline");
 }
 
 /*[clinic input]
@@ -1837,14 +1970,17 @@ _curses_window_insch_impl(PyCursesWindowObject *self, 
int group_left_1,
     if (!PyCurses_ConvertToChtype(self, ch, &ch_))
         return NULL;
 
+    const char *funcname;
     if (!group_left_1) {
         rtn = winsch(self->win, ch_ | (attr_t)attr);
+        funcname = "winsch";
     }
     else {
         rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr);
+        funcname = "mvwwinsch";
     }
 
-    return PyCursesCheckERR_ForWin(self, rtn, "insch");
+    return curses_window_check_err(self, rtn, funcname, "insch");
 }
 
 /*[clinic input]
@@ -2003,27 +2139,33 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, 
int group_left_1,
     }
 #ifdef HAVE_NCURSESW
     if (strtype == 2) {
-        funcname = "inswstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwins_wstr(self->win,y,x,wstr);
-        else
+            funcname = "mvwins_wstr";
+        }
+        else {
             rtn = wins_wstr(self->win,wstr);
+            funcname = "wins_wstr";
+        }
         PyMem_Free(wstr);
     }
     else
 #endif
     {
         const char *str = PyBytes_AS_STRING(bytesobj);
-        funcname = "insstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwinsstr(self->win,y,x,str);
-        else
+            funcname = "mvwinsstr";
+        }
+        else {
             rtn = winsstr(self->win,str);
+            funcname = "winsstr";
+        }
         Py_DECREF(bytesobj);
     }
     if (use_attr)
         (void)wattrset(self->win,attr_old);
-    return PyCursesCheckERR_ForWin(self, rtn, funcname);
+    return curses_window_check_err(self, rtn, funcname, "insstr");
 }
 
 /*[clinic input]
@@ -2088,27 +2230,33 @@ _curses_window_insnstr_impl(PyCursesWindowObject *self, 
int group_left_1,
     }
 #ifdef HAVE_NCURSESW
     if (strtype == 2) {
-        funcname = "insn_wstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwins_nwstr(self->win,y,x,wstr,n);
-        else
+            funcname = "mvwins_nwstr";
+        }
+        else {
             rtn = wins_nwstr(self->win,wstr,n);
+            funcname = "wins_nwstr";
+        }
         PyMem_Free(wstr);
     }
     else
 #endif
     {
         const char *str = PyBytes_AS_STRING(bytesobj);
-        funcname = "insnstr";
-        if (use_xy)
+        if (use_xy) {
             rtn = mvwinsnstr(self->win,y,x,str,n);
-        else
+            funcname = "mvwinsnstr";
+        }
+        else {
             rtn = winsnstr(self->win,str,n);
+            funcname = "winsnstr";
+        }
         Py_DECREF(bytesobj);
     }
     if (use_attr)
         (void)wattrset(self->win,attr_old);
-    return PyCursesCheckERR_ForWin(self, rtn, funcname);
+    return curses_window_check_err(self, rtn, funcname, "insnstr");
 }
 
 /*[clinic input]
@@ -2130,8 +2278,7 @@ _curses_window_is_linetouched_impl(PyCursesWindowObject 
*self, int line)
     int erg;
     erg = is_linetouched(self->win, line);
     if (erg == ERR) {
-        PyErr_SetString(PyExc_TypeError,
-                        "is_linetouched: line number outside of boundaries");
+        curses_window_set_error(self, "is_linetouched", NULL);
         return NULL;
     }
     return PyBool_FromLong(erg);
@@ -2195,7 +2342,8 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject 
*self)
         rtn = pnoutrefresh(self->win, pminrow, pmincol,
                            sminrow, smincol, smaxrow, smaxcol);
         Py_END_ALLOW_THREADS
-        return PyCursesCheckERR_ForWin(self, rtn, "pnoutrefresh");
+        return curses_window_check_err(self, rtn,
+                                       "pnoutrefresh", "noutrefresh");
     }
     if (group_right_1) {
         PyErr_SetString(PyExc_TypeError,
@@ -2206,7 +2354,7 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject 
*self)
     Py_BEGIN_ALLOW_THREADS
     rtn = wnoutrefresh(self->win);
     Py_END_ALLOW_THREADS
-    return PyCursesCheckERR_ForWin(self, rtn, "wnoutrefresh");
+    return curses_window_check_err(self, rtn, "wnoutrefresh", "noutrefresh");
 }
 
 /*[clinic input]
@@ -2248,11 +2396,11 @@ _curses_window_overlay_impl(PyCursesWindowObject *self,
     if (group_right_1) {
         rtn = copywin(self->win, destwin->win, sminrow, smincol,
                       dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
-        return PyCursesCheckERR_ForWin(self, rtn, "copywin");
+        return curses_window_check_err(self, rtn, "copywin", "overlay");
     }
     else {
         rtn = overlay(self->win, destwin->win);
-        return PyCursesCheckERR_ForWin(self, rtn, "overlay");
+        return curses_window_check_err(self, rtn, "overlay", NULL);
     }
 }
 
@@ -2296,11 +2444,11 @@ _curses_window_overwrite_impl(PyCursesWindowObject 
*self,
     if (group_right_1) {
         rtn = copywin(self->win, destwin->win, sminrow, smincol,
                       dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
-        return PyCursesCheckERR_ForWin(self, rtn, "copywin");
+        return curses_window_check_err(self, rtn, "copywin", "overwrite");
     }
     else {
         rtn = overwrite(self->win, destwin->win);
-        return PyCursesCheckERR_ForWin(self, rtn, "overwrite");
+        return curses_window_check_err(self, rtn, "overwrite", NULL);
     }
 }
 
@@ -2329,7 +2477,7 @@ _curses_window_putwin_impl(PyCursesWindowObject *self, 
PyObject *file)
         return PyErr_SetFromErrno(PyExc_OSError);
     if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
         goto exit;
-    res = PyCursesCheckERR_ForWin(self, putwin(self->win, fp), "putwin");
+    res = curses_window_check_err(self, putwin(self->win, fp), "putwin", NULL);
     if (res == NULL)
         goto exit;
     fseek(fp, 0, 0);
@@ -2368,7 +2516,8 @@ static PyObject *
 _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num)
 /*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/
 {
-    return PyCursesCheckERR_ForWin(self, wredrawln(self->win,beg,num), 
"redrawln");
+    int rtn = wredrawln(self->win,beg, num);
+    return curses_window_check_err(self, rtn, "wredrawln", "redrawln");
 }
 
 /*[clinic input]
@@ -2419,7 +2568,7 @@ _curses_window_refresh_impl(PyCursesWindowObject *self, 
int group_right_1,
         rtn = prefresh(self->win, pminrow, pmincol,
                        sminrow, smincol, smaxrow, smaxcol);
         Py_END_ALLOW_THREADS
-        return PyCursesCheckERR_ForWin(self, rtn, "prefresh");
+        return curses_window_check_err(self, rtn, "prefresh", "refresh");
     }
 #endif
     if (group_right_1) {
@@ -2430,7 +2579,7 @@ _curses_window_refresh_impl(PyCursesWindowObject *self, 
int group_right_1,
     Py_BEGIN_ALLOW_THREADS
     rtn = wrefresh(self->win);
     Py_END_ALLOW_THREADS
-    return PyCursesCheckERR_ForWin(self, rtn, "prefresh");
+    return curses_window_check_err(self, rtn, "wrefresh", "refresh");
 }
 
 /*[clinic input]
@@ -2452,7 +2601,8 @@ _curses_window_setscrreg_impl(PyCursesWindowObject *self, 
int top,
                               int bottom)
 /*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/
 {
-    return PyCursesCheckERR_ForWin(self, wsetscrreg(self->win, top, bottom), 
"wsetscrreg");
+    int rtn = wsetscrreg(self->win, top, bottom);
+    return curses_window_check_err(self, rtn, "wsetscrreg", "setscrreg");
 }
 
 /*[clinic input]
@@ -2482,19 +2632,23 @@ _curses_window_subwin_impl(PyCursesWindowObject *self, 
int group_left_1,
 /*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/
 {
     WINDOW *win;
+    const char *funcname;
 
     /* printf("Subwin: %i %i %i %i   \n", nlines, ncols, begin_y, begin_x); */
 #ifdef py_is_pad
     if (py_is_pad(self->win)) {
         win = subpad(self->win, nlines, ncols, begin_y, begin_x);
+        funcname = "subpad";
     }
     else
 #endif
+    {
         win = subwin(self->win, nlines, ncols, begin_y, begin_x);
+        funcname = "subwin";
+    }
 
     if (win == NULL) {
-        cursesmodule_state *state = get_cursesmodule_state_by_win(self);
-        PyErr_SetString(state->error, catchall_NULL);
+        curses_window_set_null_error(self, funcname, "subwin");
         return NULL;
     }
 
@@ -2521,12 +2675,17 @@ _curses_window_scroll_impl(PyCursesWindowObject *self, 
int group_right_1,
                            int lines)
 /*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/
 {
+    int rtn;
+    const char *funcname;
     if (!group_right_1) {
-        return PyCursesCheckERR_ForWin(self, scroll(self->win), "scroll");
+        rtn = scroll(self->win);
+        funcname = "scroll";
     }
     else {
-        return PyCursesCheckERR_ForWin(self, wscrl(self->win, lines), 
"scroll");
+        rtn = wscrl(self->win, lines);
+        funcname = "wscrl";
     }
+    return curses_window_check_err(self, rtn, funcname, "scroll");
 }
 
 /*[clinic input]
@@ -2550,12 +2709,17 @@ _curses_window_touchline_impl(PyCursesWindowObject 
*self, int start,
                               int count, int group_right_1, int changed)
 /*[clinic end generated code: output=65d05b3f7438c61d input=a98aa4f79b6be845]*/
 {
+    int rtn;
+    const char *funcname;
     if (!group_right_1) {
-        return PyCursesCheckERR_ForWin(self, touchline(self->win, start, 
count), "touchline");
+        rtn = touchline(self->win, start, count);
+        funcname = "touchline";
     }
     else {
-        return PyCursesCheckERR_ForWin(self, wtouchln(self->win, start, count, 
changed), "touchline");
+        rtn = wtouchln(self->win, start, count, changed);
+        funcname = "wtouchln";
     }
+    return curses_window_check_err(self, rtn, funcname, "touchline");
 }
 
 /*[clinic input]
@@ -2593,10 +2757,13 @@ _curses_window_vline_impl(PyCursesWindowObject *self, 
int group_left_1,
     if (!PyCurses_ConvertToChtype(self, ch, &ch_))
         return NULL;
     if (group_left_1) {
-        if (wmove(self->win, y, x) == ERR)
-            return PyCursesCheckERR_ForWin(self, ERR, "wmove");
+        if (wmove(self->win, y, x) == ERR) {
+            curses_window_set_error(self, "wmove", "vline");
+            return NULL;
+        }
     }
-    return PyCursesCheckERR_ForWin(self, wvline(self->win, ch_ | (attr_t)attr, 
n), "vline");
+    int rtn = wvline(self->win, ch_ | (attr_t)attr, n);
+    return curses_window_check_err(self, rtn, "wvline", "vline");
 }
 
 static PyObject *
@@ -2761,26 +2928,39 @@ static PyType_Spec PyCursesWindow_Type_spec = {
 
 /* -------------------------------------------------------*/
 
-/* Function Body Macros - They are ugly but very, very useful. ;-)
-
-   X - function name
-   TYPE - parameter Type
-   ERGSTR - format string for construction of the return value
-   PARSESTR - format string for argument parsing
-   */
+/*
+ * Macros for implementing simple module's methods.
+ *
+ * Parameters
+ *
+ *  X       The name of the curses C function or macro to invoke.
+ *  FLAG    When false, prefixes the function name with 'no' at runtime,
+ *          This parameter is present in the signature and auto-generated
+ *          by Argument Clinic.
+ *
+ * These macros should only be used for generating the body of
+ * the module's methods since they need a module reference.
+ */
 
 #define NoArgNoReturnFunctionBody(X) \
 { \
   PyCursesStatefulInitialised(module); \
-  return PyCursesCheckERR(module, X(), # X); }
-
-#define NoArgOrFlagNoReturnFunctionBody(X, flag) \
-{ \
-    PyCursesStatefulInitialised(module); \
-    if (flag) \
-        return PyCursesCheckERR(module, X(), # X); \
-    else \
-        return PyCursesCheckERR(module, no ## X(), # X); \
+  return curses_check_err(module, X(), # X, NULL); }
+
+#define NoArgOrFlagNoReturnFunctionBody(X, FLAG)            \
+{                                                           \
+    PyCursesStatefulInitialised(module);                    \
+    int rtn;                                                \
+    const char *funcname;                                   \
+    if (FLAG) {                                             \
+        rtn = X();                                          \
+        funcname = # X;                                     \
+    }                                                       \
+    else {                                                  \
+        rtn = no ## X();                                    \
+        funcname = "no" # X;                                \
+    }                                                       \
+    return curses_check_err(module, rtn, funcname, # X);    \
 }
 
 #define NoArgReturnIntFunctionBody(X) \
@@ -2788,7 +2968,6 @@ static PyType_Spec PyCursesWindow_Type_spec = {
  PyCursesStatefulInitialised(module); \
  return PyLong_FromLong((long) X()); }
 
-
 #define NoArgReturnStringFunctionBody(X) \
 { \
   PyCursesStatefulInitialised(module); \
@@ -2903,9 +3082,8 @@ _curses_color_content_impl(PyObject *module, int 
color_number)
     PyCursesStatefulInitialisedColor(module);
 
     if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) == ERR) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_Format(state->error, "%s() returned ERR",
-                     Py_STRINGIFY(_COLOR_CONTENT_FUNC));
+        const char *funcname = Py_STRINGIFY(_COLOR_CONTENT_FUNC);
+        curses_set_error(module, funcname, "color_content");
         return NULL;
     }
 
@@ -2959,7 +3137,10 @@ _curses_curs_set_impl(PyObject *module, int visibility)
     PyCursesStatefulInitialised(module);
 
     erg = curs_set(visibility);
-    if (erg == ERR) return PyCursesCheckERR(module, erg, "curs_set");
+    if (erg == ERR) {
+        curses_set_error(module, "curs_set", NULL);
+        return NULL;
+    }
 
     return PyLong_FromLong((long) erg);
 }
@@ -3010,7 +3191,7 @@ _curses_delay_output_impl(PyObject *module, int ms)
 {
     PyCursesStatefulInitialised(module);
 
-    return PyCursesCheckERR(module, delay_output(ms), "delay_output");
+    return curses_check_err(module, delay_output(ms), "delay_output", NULL);
 }
 
 /*[clinic input]
@@ -3143,8 +3324,7 @@ _curses_getmouse_impl(PyObject *module)
 
     rtn = getmouse( &event );
     if (rtn == ERR) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, "getmouse() returned ERR");
+        curses_set_error(module, "getmouse", NULL);
         return NULL;
     }
     return Py_BuildValue("(hiiik)",
@@ -3182,7 +3362,7 @@ _curses_ungetmouse_impl(PyObject *module, short id, int 
x, int y, int z,
     event.y = y;
     event.z = z;
     event.bstate = bstate;
-    return PyCursesCheckERR(module, ungetmouse(&event), "ungetmouse");
+    return curses_check_err(module, ungetmouse(&event), "ungetmouse", NULL);
 }
 #endif
 
@@ -3238,8 +3418,7 @@ _curses_getwin(PyObject *module, PyObject *file)
     fseek(fp, 0, 0);
     win = getwin(fp);
     if (win == NULL) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, catchall_NULL);
+        curses_set_null_error(module, "getwin", NULL);
         goto error;
     }
     cursesmodule_state *state = get_cursesmodule_state(module);
@@ -3268,7 +3447,7 @@ _curses_halfdelay_impl(PyObject *module, unsigned char 
tenths)
 {
     PyCursesStatefulInitialised(module);
 
-    return PyCursesCheckERR(module, halfdelay(tenths), "halfdelay");
+    return curses_check_err(module, halfdelay(tenths), "halfdelay", NULL);
 }
 
 /*[clinic input]
@@ -3353,9 +3532,10 @@ _curses_init_color_impl(PyObject *module, int 
color_number, short r, short g,
     PyCursesStatefulInitialised(module);
     PyCursesStatefulInitialisedColor(module);
 
-    return PyCursesCheckERR(module,
+    return curses_check_err(module,
                             _CURSES_INIT_COLOR_FUNC(color_number, r, g, b),
-                            Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC));
+                            Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC),
+                            NULL);
 }
 
 /*[clinic input]
@@ -3389,9 +3569,8 @@ _curses_init_pair_impl(PyObject *module, int pair_number, 
int fg, int bg)
                          COLOR_PAIRS - 1);
         }
         else {
-            cursesmodule_state *state = get_cursesmodule_state(module);
-            PyErr_Format(state->error, "%s() returned ERR",
-                         Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC));
+            const char *funcname = Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC);
+            curses_set_error(module, funcname, "init_pair");
         }
         return NULL;
     }
@@ -3422,8 +3601,7 @@ _curses_initscr_impl(PyObject *module)
     win = initscr();
 
     if (win == NULL) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, catchall_NULL);
+        curses_set_null_error(module, "initscr", NULL);
         return NULL;
     }
 
@@ -3628,7 +3806,7 @@ _curses_set_escdelay_impl(PyObject *module, int ms)
         return NULL;
     }
 
-    return PyCursesCheckERR(module, set_escdelay(ms), "set_escdelay");
+    return curses_check_err(module, set_escdelay(ms), "set_escdelay", NULL);
 }
 
 /*[clinic input]
@@ -3667,7 +3845,7 @@ _curses_set_tabsize_impl(PyObject *module, int size)
         return NULL;
     }
 
-    return PyCursesCheckERR(module, set_tabsize(size), "set_tabsize");
+    return curses_check_err(module, set_tabsize(size), "set_tabsize", NULL);
 }
 #endif
 
@@ -3685,7 +3863,7 @@ _curses_intrflush_impl(PyObject *module, int flag)
 {
     PyCursesStatefulInitialised(module);
 
-    return PyCursesCheckERR(module, intrflush(NULL, flag), "intrflush");
+    return curses_check_err(module, intrflush(NULL, flag), "intrflush", NULL);
 }
 
 /*[clinic input]
@@ -3798,7 +3976,7 @@ _curses_meta_impl(PyObject *module, int yes)
 {
     PyCursesStatefulInitialised(module);
 
-    return PyCursesCheckERR(module, meta(stdscr, yes), "meta");
+    return curses_check_err(module, meta(stdscr, yes), "meta", NULL);
 }
 
 #ifdef NCURSES_MOUSE_VERSION
@@ -3821,8 +3999,12 @@ _curses_mouseinterval_impl(PyObject *module, int 
interval)
 /*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/
 {
     PyCursesStatefulInitialised(module);
-
-    return PyCursesCheckERR(module, mouseinterval(interval), "mouseinterval");
+    int value = mouseinterval(interval);
+    if (value == ERR) {
+        curses_set_error(module, "mouseinterval", NULL);
+        return NULL;
+    }
+    return PyLong_FromLong(value);
 }
 
 /*[clinic input]
@@ -3898,8 +4080,7 @@ _curses_newpad_impl(PyObject *module, int nlines, int 
ncols)
     win = newpad(nlines, ncols);
 
     if (win == NULL) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, catchall_NULL);
+        curses_set_null_error(module, "newpad", NULL);
         return NULL;
     }
 
@@ -3939,8 +4120,7 @@ _curses_newwin_impl(PyObject *module, int nlines, int 
ncols,
 
     win = newwin(nlines,ncols,begin_y,begin_x);
     if (win == NULL) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, catchall_NULL);
+        curses_set_null_error(module, "newwin", NULL);
         return NULL;
     }
 
@@ -4059,9 +4239,8 @@ _curses_pair_content_impl(PyObject *module, int 
pair_number)
                          COLOR_PAIRS - 1);
         }
         else {
-            cursesmodule_state *state = get_cursesmodule_state(module);
-            PyErr_Format(state->error, "%s() returned ERR",
-                         Py_STRINGIFY(_CURSES_PAIR_CONTENT_FUNC));
+            const char *funcname = Py_STRINGIFY(_CURSES_PAIR_CONTENT_FUNC);
+            curses_set_error(module, funcname, "pair_content");
         }
         return NULL;
     }
@@ -4105,7 +4284,7 @@ static PyObject *
 _curses_putp_impl(PyObject *module, const char *string)
 /*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/
 {
-    return PyCursesCheckERR(module, putp(string), "putp");
+    return curses_check_err(module, putp(string), "putp", NULL);
 }
 
 /*[clinic input]
@@ -4279,10 +4458,12 @@ _curses_resizeterm_impl(PyObject *module, short nlines, 
short ncols)
 /*[clinic end generated code: output=4de3abab50c67f02 input=414e92a63e3e9899]*/
 {
     PyObject *result;
+    int code;
 
     PyCursesStatefulInitialised(module);
 
-    result = PyCursesCheckERR(module, resizeterm(nlines, ncols), "resizeterm");
+    code = resizeterm(nlines, ncols);
+    result = curses_check_err(module, code, "resizeterm", NULL);
     if (!result)
         return NULL;
     if (!update_lines_cols(module)) {
@@ -4318,10 +4499,12 @@ _curses_resize_term_impl(PyObject *module, short 
nlines, short ncols)
 /*[clinic end generated code: output=46c6d749fa291dbd input=276afa43d8ea7091]*/
 {
     PyObject *result;
+    int code;
 
     PyCursesStatefulInitialised(module);
 
-    result = PyCursesCheckERR(module, resize_term(nlines, ncols), 
"resize_term");
+    code = resize_term(nlines, ncols);
+    result = curses_check_err(module, code, "resize_term", NULL);
     if (!result)
         return NULL;
     if (!update_lines_cols(module)) {
@@ -4390,8 +4573,7 @@ _curses_start_color_impl(PyObject *module)
     PyCursesStatefulInitialised(module);
 
     if (start_color() == ERR) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, "start_color() returned ERR");
+        curses_set_error(module, "start_color", NULL);
         return NULL;
     }
 
@@ -4543,8 +4725,7 @@ _curses_tparm_impl(PyObject *module, const char *str, int 
i1, int i2, int i3,
 
     result = tparm((char *)str,i1,i2,i3,i4,i5,i6,i7,i8,i9);
     if (!result) {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, "tparm() returned NULL");
+        curses_set_null_error(module, "tparm", NULL);
         return NULL;
     }
 
@@ -4570,7 +4751,7 @@ _curses_typeahead_impl(PyObject *module, int fd)
 {
     PyCursesStatefulInitialised(module);
 
-    return PyCursesCheckERR(module, typeahead( fd ), "typeahead");
+    return curses_check_err(module, typeahead(fd), "typeahead", NULL);
 }
 #endif
 
@@ -4620,7 +4801,7 @@ _curses_ungetch(PyObject *module, PyObject *ch)
     if (!PyCurses_ConvertToChtype(NULL, ch, &ch_))
         return NULL;
 
-    return PyCursesCheckERR(module, ungetch(ch_), "ungetch");
+    return curses_check_err(module, ungetch(ch_), "ungetch", NULL);
 }
 
 #ifdef HAVE_NCURSESW
@@ -4690,7 +4871,7 @@ _curses_unget_wch(PyObject *module, PyObject *ch)
 
     if (!PyCurses_ConvertToWchar_t(ch, &wch))
         return NULL;
-    return PyCursesCheckERR(module, unget_wch(wch), "unget_wch");
+    return curses_check_err(module, unget_wch(wch), "unget_wch", NULL);
 }
 #endif
 
@@ -4739,13 +4920,7 @@ _curses_use_default_colors_impl(PyObject *module)
     PyCursesStatefulInitialisedColor(module);
 
     code = use_default_colors();
-    if (code != ERR) {
-        Py_RETURN_NONE;
-    } else {
-        cursesmodule_state *state = get_cursesmodule_state(module);
-        PyErr_SetString(state->error, "use_default_colors() returned ERR");
-        return NULL;
-    }
+    return curses_check_err(module, code, "use_default_colors", NULL);
 }
 
 /*[clinic input]

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to