https://github.com/python/cpython/commit/51762b6cadb8f316dd783716bc5c168c2e2d07f0
commit: 51762b6cadb8f316dd783716bc5c168c2e2d07f0
branch: main
author: Bénédikt Tran <[email protected]>
committer: picnixz <[email protected]>
date: 2025-05-27T10:51:05+02:00
summary:
gh-134210: handle signals in `_curses.window.getch` (#134326)
files:
A Misc/NEWS.d/next/Library/2025-05-24-13-10-35.gh-issue-134210.0IuMY2.rst
M Modules/_cursesmodule.c
M Modules/clinic/_cursesmodule.c.h
diff --git
a/Misc/NEWS.d/next/Library/2025-05-24-13-10-35.gh-issue-134210.0IuMY2.rst
b/Misc/NEWS.d/next/Library/2025-05-24-13-10-35.gh-issue-134210.0IuMY2.rst
new file mode 100644
index 00000000000000..b440e8308db6a2
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-05-24-13-10-35.gh-issue-134210.0IuMY2.rst
@@ -0,0 +1,2 @@
+:func:`curses.window.getch` now correctly handles signals. Patch by Bénédikt
+Tran.
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 55d664cebe31ec..27469d75079f45 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -1656,7 +1656,7 @@ _curses_window_getbkgd_impl(PyCursesWindowObject *self)
}
/*[clinic input]
-_curses.window.getch -> int
+_curses.window.getch
[
y: int
@@ -1673,10 +1673,10 @@ keypad keys and so on return numbers higher than 256.
In no-delay mode, -1
is returned if there is no input, else getch() waits until a key is pressed.
[clinic start generated code]*/
-static int
+static PyObject *
_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
int y, int x)
-/*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/
+/*[clinic end generated code: output=e1639e87d545e676 input=73f350336b1ee8c8]*/
{
int rtn;
@@ -1689,7 +1689,17 @@ _curses_window_getch_impl(PyCursesWindowObject *self,
int group_right_1,
}
Py_END_ALLOW_THREADS
- return rtn;
+ if (rtn == ERR) {
+ // We suppress ERR returned by wgetch() in nodelay mode
+ // after we handled possible interruption signals.
+ if (PyErr_CheckSignals()) {
+ return NULL;
+ }
+ // ERR is an implementation detail, so to be on the safe side,
+ // we forcibly set the return value to -1 as documented above.
+ rtn = -1;
+ }
+ return PyLong_FromLong(rtn);
}
/*[clinic input]
diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h
index 552360eb80a545..a898a7e17cf8d1 100644
--- a/Modules/clinic/_cursesmodule.c.h
+++ b/Modules/clinic/_cursesmodule.c.h
@@ -768,7 +768,7 @@ PyDoc_STRVAR(_curses_window_getch__doc__,
#define _CURSES_WINDOW_GETCH_METHODDEF \
{"getch", (PyCFunction)_curses_window_getch, METH_VARARGS,
_curses_window_getch__doc__},
-static int
+static PyObject *
_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
int y, int x);
@@ -779,7 +779,6 @@ _curses_window_getch(PyObject *self, PyObject *args)
int group_right_1 = 0;
int y = 0;
int x = 0;
- int _return_value;
switch (PyTuple_GET_SIZE(args)) {
case 0:
@@ -794,11 +793,7 @@ _curses_window_getch(PyObject *self, PyObject *args)
PyErr_SetString(PyExc_TypeError, "_curses.window.getch requires 0
to 2 arguments");
goto exit;
}
- _return_value = _curses_window_getch_impl((PyCursesWindowObject *)self,
group_right_1, y, x);
- if ((_return_value == -1) && PyErr_Occurred()) {
- goto exit;
- }
- return_value = PyLong_FromLong((long)_return_value);
+ return_value = _curses_window_getch_impl((PyCursesWindowObject *)self,
group_right_1, y, x);
exit:
return return_value;
@@ -4440,4 +4435,4 @@ _curses_has_extended_color_support(PyObject *module,
PyObject *Py_UNUSED(ignored
#ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=42b2923d88c8d0f6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=7753612d7613903c input=a9049054013a1b77]*/
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]