https://github.com/python/cpython/commit/d610f11d21241d353b25843f66e51098a5c0ddad
commit: d610f11d21241d353b25843f66e51098a5c0ddad
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-06-08T09:10:52+02:00
summary:

gh-133579: correctly report C curses errors in `_curses_panel` (#134629)

This is a follow-up to ee36db550076e5a9185444ffbc53eaf8157ef04c.

files:
M Modules/_curses_panel.c
M Modules/clinic/_curses_panel.c.h

diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c
index eecf7a1c8a1e56..d7acfc6a06a974 100644
--- a/Modules/_curses_panel.c
+++ b/Modules/_curses_panel.c
@@ -17,6 +17,7 @@ static const char PyCursesVersion[] = "2.1";
 
 #include "Python.h"
 
+#define CURSES_PANEL_MODULE
 #include "py_curses.h"
 
 #if defined(HAVE_NCURSESW_PANEL_H)
@@ -28,10 +29,12 @@ static const char PyCursesVersion[] = "2.1";
 #endif
 
 typedef struct {
-    PyObject *PyCursesError;
+    PyObject *error;
     PyTypeObject *PyCursesPanel_Type;
 } _curses_panel_state;
 
+typedef struct PyCursesPanelObject PyCursesPanelObject;
+
 static inline _curses_panel_state *
 get_curses_panel_state(PyObject *module)
 {
@@ -40,11 +43,30 @@ get_curses_panel_state(PyObject *module)
     return (_curses_panel_state *)state;
 }
 
+static inline _curses_panel_state *
+get_curses_panel_state_by_panel(PyCursesPanelObject *panel)
+{
+    /*
+     * Note: 'state' may be NULL if Py_TYPE(panel) is not a heap
+     * type associated with this module, but the compiler would
+     * have likely already complained with an "invalid pointer
+     * type" at compile-time.
+     *
+     * To make it more robust, all functions recovering a module's
+     * state from an object should expect to return NULL with an
+     * exception set (in contrast to functions recovering a module's
+     * state from a module itself).
+     */
+    void *state = PyType_GetModuleState(Py_TYPE(panel));
+    assert(state != NULL);
+    return (_curses_panel_state *)state;
+}
+
 static int
 _curses_panel_clear(PyObject *mod)
 {
     _curses_panel_state *state = get_curses_panel_state(mod);
-    Py_CLEAR(state->PyCursesError);
+    Py_CLEAR(state->error);
     Py_CLEAR(state->PyCursesPanel_Type);
     return 0;
 }
@@ -54,7 +76,7 @@ _curses_panel_traverse(PyObject *mod, visitproc visit, void 
*arg)
 {
     Py_VISIT(Py_TYPE(mod));
     _curses_panel_state *state = get_curses_panel_state(mod);
-    Py_VISIT(state->PyCursesError);
+    Py_VISIT(state->error);
     Py_VISIT(state->PyCursesPanel_Type);
     return 0;
 }
@@ -65,28 +87,149 @@ _curses_panel_free(void *mod)
     (void)_curses_panel_clear((PyObject *)mod);
 }
 
+/* Utility Error Procedures
+ *
+ * The naming and implementations are identical to those in _cursesmodule.c.
+ * Functions that are not yet needed (for instance, reporting an ERR value
+ * from a module-wide function, namely curses_panel_set_error()) are
+ * omitted and should only be added if needed.
+ */
+
+static void
+_curses_panel_format_error(_curses_panel_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_panel_set_error(_curses_panel_state *state,
+                        const char *curses_funcname,
+                        const char *python_funcname)
+{
+    _curses_panel_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 void
+_curses_panel_set_null_error(_curses_panel_state *state,
+                             const char *curses_funcname,
+                             const char *python_funcname)
+{
+    _curses_panel_format_error(state, curses_funcname, python_funcname,
+                               "NULL", catchall_NULL);
+}
+
+/* Same as _curses_panel_set_null_error() for a module object. */
+static void
+curses_panel_set_null_error(PyObject *module,
+                            const char *curses_funcname,
+                            const char *python_funcname)
+{
+    _curses_panel_state *state = get_curses_panel_state(module);
+    _curses_panel_set_null_error(state, curses_funcname, python_funcname);
+}
+
+/* Same as _curses_panel_set_error() for a panel object. */
+static void
+curses_panel_panel_set_error(PyCursesPanelObject *panel,
+                             const char *curses_funcname,
+                             const char *python_funcname)
+{
+    _curses_panel_state *state = get_curses_panel_state_by_panel(panel);
+    _curses_panel_set_error(state, curses_funcname, python_funcname);
+}
+
+/* Same as _curses_panel_set_null_error() for a panel object. */
+static void
+curses_panel_panel_set_null_error(PyCursesPanelObject *panel,
+                                  const char *curses_funcname,
+                                  const char *python_funcname)
+{
+    _curses_panel_state *state = get_curses_panel_state_by_panel(panel);
+    _curses_panel_set_null_error(state, curses_funcname, python_funcname);
+}
+
+/*
+ * Indicate that a panel object couldn't be found.
+ *
+ * Use it for the following constructions:
+ *
+ * PROC caller_funcname:
+ *  pan = called_funcname()
+ *  find_po(panel)
+ *
+ * PROC caller_funcname:
+ *  find_po(self->pan)
+*/
+static void
+curses_panel_notfound_error(const char *called_funcname,
+                            const char *caller_funcname)
+{
+    assert(!(called_funcname == NULL && caller_funcname == NULL));
+    if (caller_funcname == NULL) {
+        (void)PyErr_Format(PyExc_RuntimeError,
+                           "%s(): cannot find panel object",
+                           called_funcname);
+    }
+    else {
+        (void)PyErr_Format(PyExc_RuntimeError,
+                           "%s() (called by %s()): cannot find panel object",
+                           called_funcname, caller_funcname);
+    }
+}
+
 /* Utility Functions */
 
 /*
- * 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 different from ERR (implementation-defined).
+ * Otherwise, set an exception using curses_panel_panel_set_error() and
+ * the remaining arguments, and return NULL.
+ */
 static PyObject *
-PyCursesCheckERR(_curses_panel_state *state, int code, const char *fname)
+curses_panel_panel_check_err(PyCursesPanelObject *panel, int code,
+                             const char *curses_funcname,
+                             const char *python_funcname)
 {
     if (code != ERR) {
         Py_RETURN_NONE;
     }
-    else {
-        if (fname == NULL) {
-            PyErr_SetString(state->PyCursesError, catchall_ERR);
-        }
-        else {
-            PyErr_Format(state->PyCursesError, "%s() returned ERR", fname);
-        }
-        return NULL;
-    }
+    curses_panel_panel_set_error(panel, curses_funcname, python_funcname);
+    return NULL;
 }
 
 /*****************************************************************************
@@ -95,7 +238,7 @@ PyCursesCheckERR(_curses_panel_state *state, int code, const 
char *fname)
 
 /* Definition of the panel object and panel type */
 
-typedef struct {
+typedef struct PyCursesPanelObject {
     PyObject_HEAD
     PANEL *pan;
     PyCursesWindowObject *wo;   /* for reference counts */
@@ -144,8 +287,11 @@ insert_lop(PyCursesPanelObject *po)
     return 0;
 }
 
-/* Remove the panel object from lop */
-static void
+/* Remove the panel object from lop.
+ *
+ * Return -1 on error but do NOT set an exception; otherwise return 0.
+ */
+static int
 remove_lop(PyCursesPanelObject *po)
 {
     list_of_panels *temp, *n;
@@ -154,25 +300,23 @@ remove_lop(PyCursesPanelObject *po)
     if (temp->po == po) {
         lop = temp->next;
         PyMem_Free(temp);
-        return;
+        return 0;
     }
     while (temp->next == NULL || temp->next->po != po) {
         if (temp->next == NULL) {
-            PyErr_SetString(PyExc_RuntimeError,
-                            "remove_lop: can't find Panel Object");
-            return;
+            return -1;
         }
         temp = temp->next;
     }
     n = temp->next->next;
     PyMem_Free(temp->next);
     temp->next = n;
-    return;
+    return 0;
 }
 
 /* Return the panel object that corresponds to pan */
 static PyCursesPanelObject *
-find_po(PANEL *pan)
+find_po_impl(PANEL *pan)
 {
     list_of_panels *temp;
     for (temp = lop; temp->po->pan != pan; temp = temp->next)
@@ -180,6 +324,17 @@ find_po(PANEL *pan)
     return temp->po;
 }
 
+/* Same as find_po_impl() but with caller context information. */
+static PyCursesPanelObject *
+find_po(PANEL *pan, const char *called_funcname, const char *caller_funcname)
+{
+    PyCursesPanelObject *res = find_po_impl(pan);
+    if (res == NULL) {
+        curses_panel_notfound_error(called_funcname, caller_funcname);
+    }
+    return res;
+}
+
 /*[clinic input]
 module _curses_panel
 class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type"
@@ -193,67 +348,59 @@ class _curses_panel.panel "PyCursesPanelObject *" 
"&PyCursesPanel_Type"
 /*[clinic input]
 _curses_panel.panel.bottom
 
-    cls: defining_class
-
 Push the panel to the bottom of the stack.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=8ec7fbbc08554021 input=6b7d2c0578b5a1c4]*/
+_curses_panel_panel_bottom_impl(PyCursesPanelObject *self)
+/*[clinic end generated code: output=7aa7d14d7e1d1ce6 input=b6c920c071b61e2e]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-    return PyCursesCheckERR(state, bottom_panel(self->pan), "bottom");
+    int rtn = bottom_panel(self->pan);
+    return curses_panel_panel_check_err(self, rtn, "bottom_panel", "bottom");
 }
 
 /*[clinic input]
 _curses_panel.panel.hide
 
-    cls: defining_class
-
 Hide the panel.
 
 This does not delete the object, it just makes the window on screen invisible.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=cc6ab7203cdc1450 input=1bfc741f473e6055]*/
+_curses_panel_panel_hide_impl(PyCursesPanelObject *self)
+/*[clinic end generated code: output=a7bbbd523e1eab49 input=f6ab884e99386118]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-    return PyCursesCheckERR(state, hide_panel(self->pan), "hide");
+    int rtn = hide_panel(self->pan);
+    return curses_panel_panel_check_err(self, rtn, "hide_panel", "hide");
 }
 
 /*[clinic input]
 _curses_panel.panel.show
 
-    cls: defining_class
-
 Display the panel (which might have been hidden).
 [clinic start generated code]*/
 
 static PyObject *
-_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=dc3421de375f0409 input=8122e80151cb4379]*/
+_curses_panel_panel_show_impl(PyCursesPanelObject *self)
+/*[clinic end generated code: output=6b4553ab45c97769 input=57b167bbefaa3755]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-    return PyCursesCheckERR(state, show_panel(self->pan), "show");
+    int rtn = show_panel(self->pan);
+    return curses_panel_panel_check_err(self, rtn, "show_panel", "show");
 }
 
 /*[clinic input]
 _curses_panel.panel.top
 
-    cls: defining_class
-
 Push panel to the top of the stack.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=10a072e511e873f7 input=1f372d597dda3379]*/
+_curses_panel_panel_top_impl(PyCursesPanelObject *self)
+/*[clinic end generated code: output=0f5f2f8cdd2d1777 input=be33975ec3ca0e9a]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-    return PyCursesCheckERR(state, top_panel(self->pan), "top");
+    int rtn = top_panel(self->pan);
+    return curses_panel_panel_check_err(self, rtn, "top_panel", "top");
 }
 
 /* Allocation and deallocation of Panel Objects */
@@ -287,13 +434,22 @@ PyCursesPanel_Dealloc(PyObject *self)
     tp = (PyObject *) Py_TYPE(po);
     obj = (PyObject *) panel_userptr(po->pan);
     if (obj) {
-        (void)set_panel_userptr(po->pan, NULL);
         Py_DECREF(obj);
+        if (set_panel_userptr(po->pan, NULL) == ERR) {
+            curses_panel_panel_set_error(po, "set_panel_userptr", "__del__");
+            PyErr_FormatUnraisable("Exception ignored in 
PyCursesPanel_Dealloc()");
+        }
+    }
+    if (del_panel(po->pan) == ERR && !PyErr_Occurred()) {
+        curses_panel_panel_set_error(po, "del_panel", "__del__");
+        PyErr_FormatUnraisable("Exception ignored in PyCursesPanel_Dealloc()");
     }
-    (void)del_panel(po->pan);
     if (po->wo != NULL) {
         Py_DECREF(po->wo);
-        remove_lop(po);
+        if (remove_lop(po) < 0) {
+            PyErr_SetString(PyExc_RuntimeError, "__del__: no panel object to 
delete");
+            PyErr_FormatUnraisable("Exception ignored in 
PyCursesPanel_Dealloc()");
+        }
     }
     PyObject_Free(po);
     Py_DECREF(tp);
@@ -315,18 +471,11 @@ _curses_panel_panel_above_impl(PyCursesPanelObject *self)
     PyCursesPanelObject *po;
 
     pan = panel_above(self->pan);
-
-    if (pan == NULL) {          /* valid output, it means the calling panel
-                                   is on top of the stack */
+    if (pan == NULL) {  /* valid output: it means no panel exists yet */
         Py_RETURN_NONE;
     }
-    po = find_po(pan);
-    if (po == NULL) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "panel_above: can't find Panel Object");
-        return NULL;
-    }
-    return Py_NewRef(po);
+    po = find_po(pan, "panel_above", "above");
+    return Py_XNewRef(po);
 }
 
 /* panel_below(NULL) returns the top panel in the stack. To get
@@ -345,18 +494,11 @@ _curses_panel_panel_below_impl(PyCursesPanelObject *self)
     PyCursesPanelObject *po;
 
     pan = panel_below(self->pan);
-
-    if (pan == NULL) {          /* valid output, it means the calling panel
-                                   is on the bottom of the stack */
+    if (pan == NULL) {  /* valid output: it means no panel exists yet */
         Py_RETURN_NONE;
     }
-    po = find_po(pan);
-    if (po == NULL) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "panel_below: can't find Panel Object");
-        return NULL;
-    }
-    return Py_NewRef(po);
+    po = find_po(pan, "panel_below", "below");
+    return Py_XNewRef(po);
 }
 
 /*[clinic input]
@@ -378,7 +520,6 @@ _curses_panel_panel_hidden_impl(PyCursesPanelObject *self)
 /*[clinic input]
 _curses_panel.panel.move
 
-    cls: defining_class
     y: int
     x: int
     /
@@ -387,12 +528,11 @@ Move the panel to the screen coordinates (y, x).
 [clinic start generated code]*/
 
 static PyObject *
-_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls,
-                              int y, int x)
-/*[clinic end generated code: output=ce546c93e56867da input=60a0e7912ff99849]*/
+_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x)
+/*[clinic end generated code: output=d867535a89777415 input=e0b36b78acc03fba]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-    return PyCursesCheckERR(state, move_panel(self->pan, y, x), "move_panel");
+    int rtn = move_panel(self->pan, y, x);
+    return curses_panel_panel_check_err(self, rtn, "move_panel", "move");
 }
 
 /*[clinic input]
@@ -411,7 +551,6 @@ _curses_panel_panel_window_impl(PyCursesPanelObject *self)
 /*[clinic input]
 _curses_panel.panel.replace
 
-    cls: defining_class
     win: object(type="PyCursesWindowObject *", 
subclass_of="&PyCursesWindow_Type")
     /
 
@@ -420,22 +559,17 @@ Change the window associated with the panel to the window 
win.
 
 static PyObject *
 _curses_panel_panel_replace_impl(PyCursesPanelObject *self,
-                                 PyTypeObject *cls,
                                  PyCursesWindowObject *win)
-/*[clinic end generated code: output=c71f95c212d58ae7 input=dbec7180ece41ff5]*/
+/*[clinic end generated code: output=2253a95f7b287255 input=4b1c4283987d9dfa]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-
-    PyCursesPanelObject *po = find_po(self->pan);
+    PyCursesPanelObject *po = find_po(self->pan, "replace", NULL);
     if (po == NULL) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "replace_panel: can't find Panel Object");
         return NULL;
     }
 
     int rtn = replace_panel(self->pan, win->win);
     if (rtn == ERR) {
-        PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR");
+        curses_panel_panel_set_error(self, "replace_panel", "replace");
         return NULL;
     }
     Py_SETREF(po->wo, (PyCursesWindowObject*)Py_NewRef(win));
@@ -445,7 +579,6 @@ _curses_panel_panel_replace_impl(PyCursesPanelObject *self,
 /*[clinic input]
 _curses_panel.panel.set_userptr
 
-    cls: defining_class
     obj: object
     /
 
@@ -454,8 +587,8 @@ Set the panel's user pointer to obj.
 
 static PyObject *
 _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
-                                     PyTypeObject *cls, PyObject *obj)
-/*[clinic end generated code: output=db74f3db07b28080 input=e3fee2ff7b1b8e48]*/
+                                     PyObject *obj)
+/*[clinic end generated code: output=7fa1fd23f69db71e input=d2c6a9dbefabbf39]*/
 {
     PyCursesInitialised;
     Py_INCREF(obj);
@@ -464,34 +597,27 @@ _curses_panel_panel_set_userptr_impl(PyCursesPanelObject 
*self,
     if (rc == ERR) {
         /* In case of an ncurses error, decref the new object again */
         Py_DECREF(obj);
+        curses_panel_panel_set_error(self, "set_panel_userptr", "set_userptr");
+        return NULL;
     }
-    else {
-        Py_XDECREF(oldobj);
-    }
-
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-    return PyCursesCheckERR(state, rc, "set_panel_userptr");
+    Py_XDECREF(oldobj);
+    Py_RETURN_NONE;
 }
 
 /*[clinic input]
 _curses_panel.panel.userptr
 
-    cls: defining_class
-
 Return the user pointer for the panel.
 [clinic start generated code]*/
 
 static PyObject *
-_curses_panel_panel_userptr_impl(PyCursesPanelObject *self,
-                                 PyTypeObject *cls)
-/*[clinic end generated code: output=eea6e6f39ffc0179 input=f22ca4f115e30a80]*/
+_curses_panel_panel_userptr_impl(PyCursesPanelObject *self)
+/*[clinic end generated code: output=e849c307b5dc9237 input=f78b7a47aef0fd50]*/
 {
-    _curses_panel_state *state = PyType_GetModuleState(cls);
-
     PyCursesInitialised;
     PyObject *obj = (PyObject *) panel_userptr(self->pan);
     if (obj == NULL) {
-        PyErr_SetString(state->PyCursesError, "no userptr set");
+        curses_panel_panel_set_null_error(self, "panel_userptr", "userptr");
         return NULL;
     }
 
@@ -552,18 +678,11 @@ _curses_panel_bottom_panel_impl(PyObject *module)
     PyCursesInitialised;
 
     pan = panel_above(NULL);
-
-    if (pan == NULL) {          /* valid output, it means
-                                   there's no panel at all */
+    if (pan == NULL) {  /* valid output: it means no panel exists yet */
         Py_RETURN_NONE;
     }
-    po = find_po(pan);
-    if (po == NULL) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "panel_above: can't find Panel Object");
-        return NULL;
-    }
-    return Py_NewRef(po);
+    po = find_po(pan, "panel_above", "bottom_panel");
+    return Py_XNewRef(po);
 }
 
 /*[clinic input]
@@ -579,14 +698,13 @@ static PyObject *
 _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win)
 /*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/
 {
-    _curses_panel_state *state = get_curses_panel_state(module);
-
     PANEL *pan = new_panel(win->win);
     if (pan == NULL) {
-        PyErr_SetString(state->PyCursesError, catchall_NULL);
+        curses_panel_set_null_error(module, "new_panel", NULL);
         return NULL;
     }
-    return (PyObject *)PyCursesPanel_New(state, pan, win);
+    _curses_panel_state *state = get_curses_panel_state(module);
+    return PyCursesPanel_New(state, pan, win);
 }
 
 
@@ -610,18 +728,11 @@ _curses_panel_top_panel_impl(PyObject *module)
     PyCursesInitialised;
 
     pan = panel_below(NULL);
-
-    if (pan == NULL) {          /* valid output, it means
-                                   there's no panel at all */
+    if (pan == NULL) {  /* valid output: it means no panel exists yet */
         Py_RETURN_NONE;
     }
-    po = find_po(pan);
-    if (po == NULL) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "panel_below: can't find Panel Object");
-        return NULL;
-    }
-    return Py_NewRef(po);
+    po = find_po(pan, "panel_below", "top_panel");
+    return Py_XNewRef(po);
 }
 
 /*[clinic input]
@@ -673,10 +784,10 @@ _curses_panel_exec(PyObject *mod)
     }
 
     /* For exception _curses_panel.error */
-    state->PyCursesError = PyErr_NewException(
+    state->error = PyErr_NewException(
         "_curses_panel.error", NULL, NULL);
 
-    if (PyModule_AddObjectRef(mod, "error", state->PyCursesError) < 0) {
+    if (PyModule_AddObjectRef(mod, "error", state->error) < 0) {
         return -1;
     }
 
diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h
index 6f4966825ec4bf..75cf067c8aa822 100644
--- a/Modules/clinic/_curses_panel.c.h
+++ b/Modules/clinic/_curses_panel.c.h
@@ -2,10 +2,7 @@
 preserve
 [clinic start generated code]*/
 
-#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-#  include "pycore_runtime.h"     // _Py_SINGLETON()
-#endif
-#include "pycore_modsupport.h"    // _PyArg_UnpackKeywords()
+#include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 
 PyDoc_STRVAR(_curses_panel_panel_bottom__doc__,
 "bottom($self, /)\n"
@@ -14,19 +11,15 @@ PyDoc_STRVAR(_curses_panel_panel_bottom__doc__,
 "Push the panel to the bottom of the stack.");
 
 #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF    \
-    {"bottom", _PyCFunction_CAST(_curses_panel_panel_bottom), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__},
+    {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, 
_curses_panel_panel_bottom__doc__},
 
 static PyObject *
-_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls);
+_curses_panel_panel_bottom_impl(PyCursesPanelObject *self);
 
 static PyObject *
-_curses_panel_panel_bottom(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_bottom(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
-        PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments");
-        return NULL;
-    }
-    return _curses_panel_panel_bottom_impl((PyCursesPanelObject *)self, cls);
+    return _curses_panel_panel_bottom_impl((PyCursesPanelObject *)self);
 }
 
 PyDoc_STRVAR(_curses_panel_panel_hide__doc__,
@@ -38,19 +31,15 @@ PyDoc_STRVAR(_curses_panel_panel_hide__doc__,
 "This does not delete the object, it just makes the window on screen 
invisible.");
 
 #define _CURSES_PANEL_PANEL_HIDE_METHODDEF    \
-    {"hide", _PyCFunction_CAST(_curses_panel_panel_hide), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__},
+    {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, 
_curses_panel_panel_hide__doc__},
 
 static PyObject *
-_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls);
+_curses_panel_panel_hide_impl(PyCursesPanelObject *self);
 
 static PyObject *
-_curses_panel_panel_hide(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_hide(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
-        PyErr_SetString(PyExc_TypeError, "hide() takes no arguments");
-        return NULL;
-    }
-    return _curses_panel_panel_hide_impl((PyCursesPanelObject *)self, cls);
+    return _curses_panel_panel_hide_impl((PyCursesPanelObject *)self);
 }
 
 PyDoc_STRVAR(_curses_panel_panel_show__doc__,
@@ -60,19 +49,15 @@ PyDoc_STRVAR(_curses_panel_panel_show__doc__,
 "Display the panel (which might have been hidden).");
 
 #define _CURSES_PANEL_PANEL_SHOW_METHODDEF    \
-    {"show", _PyCFunction_CAST(_curses_panel_panel_show), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__},
+    {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, 
_curses_panel_panel_show__doc__},
 
 static PyObject *
-_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls);
+_curses_panel_panel_show_impl(PyCursesPanelObject *self);
 
 static PyObject *
-_curses_panel_panel_show(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_show(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
-        PyErr_SetString(PyExc_TypeError, "show() takes no arguments");
-        return NULL;
-    }
-    return _curses_panel_panel_show_impl((PyCursesPanelObject *)self, cls);
+    return _curses_panel_panel_show_impl((PyCursesPanelObject *)self);
 }
 
 PyDoc_STRVAR(_curses_panel_panel_top__doc__,
@@ -82,19 +67,15 @@ PyDoc_STRVAR(_curses_panel_panel_top__doc__,
 "Push panel to the top of the stack.");
 
 #define _CURSES_PANEL_PANEL_TOP_METHODDEF    \
-    {"top", _PyCFunction_CAST(_curses_panel_panel_top), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__},
+    {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, 
_curses_panel_panel_top__doc__},
 
 static PyObject *
-_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls);
+_curses_panel_panel_top_impl(PyCursesPanelObject *self);
 
 static PyObject *
-_curses_panel_panel_top(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_top(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
-        PyErr_SetString(PyExc_TypeError, "top() takes no arguments");
-        return NULL;
-    }
-    return _curses_panel_panel_top_impl((PyCursesPanelObject *)self, cls);
+    return _curses_panel_panel_top_impl((PyCursesPanelObject *)self);
 }
 
 PyDoc_STRVAR(_curses_panel_panel_above__doc__,
@@ -158,36 +139,19 @@ PyDoc_STRVAR(_curses_panel_panel_move__doc__,
 "Move the panel to the screen coordinates (y, x).");
 
 #define _CURSES_PANEL_PANEL_MOVE_METHODDEF    \
-    {"move", _PyCFunction_CAST(_curses_panel_panel_move), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__},
+    {"move", _PyCFunction_CAST(_curses_panel_panel_move), METH_FASTCALL, 
_curses_panel_panel_move__doc__},
 
 static PyObject *
-_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls,
-                              int y, int x);
+_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x);
 
 static PyObject *
-_curses_panel_panel_move(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_move(PyObject *self, PyObject *const *args, Py_ssize_t 
nargs)
 {
     PyObject *return_value = NULL;
-    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
-    #else
-    #  define KWTUPLE NULL
-    #endif
-
-    static const char * const _keywords[] = {"", "", NULL};
-    static _PyArg_Parser _parser = {
-        .keywords = _keywords,
-        .fname = "move",
-        .kwtuple = KWTUPLE,
-    };
-    #undef KWTUPLE
-    PyObject *argsbuf[2];
     int y;
     int x;
 
-    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
-    if (!args) {
+    if (!_PyArg_CheckPositional("move", nargs, 2, 2)) {
         goto exit;
     }
     y = PyLong_AsInt(args[0]);
@@ -198,7 +162,7 @@ _curses_panel_panel_move(PyObject *self, PyTypeObject *cls, 
PyObject *const *arg
     if (x == -1 && PyErr_Occurred()) {
         goto exit;
     }
-    return_value = _curses_panel_panel_move_impl((PyCursesPanelObject *)self, 
cls, y, x);
+    return_value = _curses_panel_panel_move_impl((PyCursesPanelObject *)self, 
y, x);
 
 exit:
     return return_value;
@@ -229,44 +193,24 @@ PyDoc_STRVAR(_curses_panel_panel_replace__doc__,
 "Change the window associated with the panel to the window win.");
 
 #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF    \
-    {"replace", _PyCFunction_CAST(_curses_panel_panel_replace), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__},
+    {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, 
_curses_panel_panel_replace__doc__},
 
 static PyObject *
 _curses_panel_panel_replace_impl(PyCursesPanelObject *self,
-                                 PyTypeObject *cls,
                                  PyCursesWindowObject *win);
 
 static PyObject *
-_curses_panel_panel_replace(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_replace(PyObject *self, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
-    #else
-    #  define KWTUPLE NULL
-    #endif
-
-    static const char * const _keywords[] = {"", NULL};
-    static _PyArg_Parser _parser = {
-        .keywords = _keywords,
-        .fname = "replace",
-        .kwtuple = KWTUPLE,
-    };
-    #undef KWTUPLE
-    PyObject *argsbuf[1];
     PyCursesWindowObject *win;
 
-    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
-    if (!args) {
-        goto exit;
-    }
-    if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) {
-        _PyArg_BadArgument("replace", "argument 1", 
(&PyCursesWindow_Type)->tp_name, args[0]);
+    if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) {
+        _PyArg_BadArgument("replace", "argument", 
(&PyCursesWindow_Type)->tp_name, arg);
         goto exit;
     }
-    win = (PyCursesWindowObject *)args[0];
-    return_value = _curses_panel_panel_replace_impl((PyCursesPanelObject 
*)self, cls, win);
+    win = (PyCursesWindowObject *)arg;
+    return_value = _curses_panel_panel_replace_impl((PyCursesPanelObject 
*)self, win);
 
 exit:
     return return_value;
@@ -279,41 +223,19 @@ PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__,
 "Set the panel\'s user pointer to obj.");
 
 #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF    \
-    {"set_userptr", _PyCFunction_CAST(_curses_panel_panel_set_userptr), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, 
_curses_panel_panel_set_userptr__doc__},
+    {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, 
_curses_panel_panel_set_userptr__doc__},
 
 static PyObject *
 _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
-                                     PyTypeObject *cls, PyObject *obj);
+                                     PyObject *obj);
 
 static PyObject *
-_curses_panel_panel_set_userptr(PyObject *self, PyTypeObject *cls, PyObject 
*const *args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_set_userptr(PyObject *self, PyObject *obj)
 {
     PyObject *return_value = NULL;
-    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
-    #else
-    #  define KWTUPLE NULL
-    #endif
-
-    static const char * const _keywords[] = {"", NULL};
-    static _PyArg_Parser _parser = {
-        .keywords = _keywords,
-        .fname = "set_userptr",
-        .kwtuple = KWTUPLE,
-    };
-    #undef KWTUPLE
-    PyObject *argsbuf[1];
-    PyObject *obj;
-
-    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
-    if (!args) {
-        goto exit;
-    }
-    obj = args[0];
-    return_value = _curses_panel_panel_set_userptr_impl((PyCursesPanelObject 
*)self, cls, obj);
 
-exit:
+    return_value = _curses_panel_panel_set_userptr_impl((PyCursesPanelObject 
*)self, obj);
+
     return return_value;
 }
 
@@ -324,20 +246,15 @@ PyDoc_STRVAR(_curses_panel_panel_userptr__doc__,
 "Return the user pointer for the panel.");
 
 #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF    \
-    {"userptr", _PyCFunction_CAST(_curses_panel_panel_userptr), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__},
+    {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, 
_curses_panel_panel_userptr__doc__},
 
 static PyObject *
-_curses_panel_panel_userptr_impl(PyCursesPanelObject *self,
-                                 PyTypeObject *cls);
+_curses_panel_panel_userptr_impl(PyCursesPanelObject *self);
 
 static PyObject *
-_curses_panel_panel_userptr(PyObject *self, PyTypeObject *cls, PyObject *const 
*args, Py_ssize_t nargs, PyObject *kwnames)
+_curses_panel_panel_userptr(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
-        PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments");
-        return NULL;
-    }
-    return _curses_panel_panel_userptr_impl((PyCursesPanelObject *)self, cls);
+    return _curses_panel_panel_userptr_impl((PyCursesPanelObject *)self);
 }
 
 PyDoc_STRVAR(_curses_panel_bottom_panel__doc__,
@@ -424,4 +341,4 @@ _curses_panel_update_panels(PyObject *module, PyObject 
*Py_UNUSED(ignored))
 {
     return _curses_panel_update_panels_impl(module);
 }
-/*[clinic end generated code: output=36853ecb4a979814 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=db2fe491582784aa input=a9049054013a1b77]*/

_______________________________________________
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