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

This is a follow-up to ee36db550076e5a9185444ffbc53eaf8157ef04c.
This commit is contained in:
Bénédikt Tran 2025-06-08 09:10:52 +02:00 committed by GitHub
parent 8fdbbf8b18
commit d610f11d21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 277 additions and 249 deletions

View File

@ -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);
}
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_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;
}

View File

@ -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) {
if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) {
_PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg);
goto exit;
}
if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) {
_PyArg_BadArgument("replace", "argument 1", (&PyCursesWindow_Type)->tp_name, args[0]);
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;
return_value = _curses_panel_panel_set_userptr_impl((PyCursesPanelObject *)self, 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 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]*/