Skip to content

_curses.window.getch does not check for interruption signals as _curses.window.{getkey,get_wch} do #134210

Closed

Description

@picnixz

Bug report

Bug description:

In _curses.window.{getkey,get_wch}, we are checking for possible interrupting signals and say:

In no-delay mode, an exception is raised if there is no input

However, in getch, we say:

In no-delay mode, -1 is returned if there is no input.

In particular, I think we should also check for signals and possibly raise an exception if PyErr_CheckSignals fails, and otherwise return -1 as documented. (note that getch returns ERR in no-delay mode, see https://linux.die.net/man/3/wgetch).

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

Activity

  1. self-assigned this
    on May 19, 2025
  2. zydtiger commented on May 19, 2025

    @zydtiger
    Contributor

    Hi! I think this fix should raise an error when PyErr_CheckSignals() failed. This is copied from the get_wch() no-delay code:

    static int
    _curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
                              int y, int x)
    /*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/
    {
        int rtn;
    
        Py_BEGIN_ALLOW_THREADS
        if (!group_right_1) {
            rtn = wgetch(self->win);
        }
        else {
            rtn = mvwgetch(self->win, y, x);
        }
        Py_END_ALLOW_THREADS
    
        /* getch() returns ERR in nodelay mode */
        if (PyErr_CheckSignals()) {
          cursesmodule_state *state = get_cursesmodule_state_by_win(self);
          const char *funcname = group_right_1 ? "mvwgetch" : "wgetch";
          PyErr_Format(state->error, "getch(): %s(): no input", funcname);
          return ERR;
        }
    
        return rtn;
    }
  3. zydtiger commented on May 19, 2025

    @zydtiger
    Contributor

    Another potential issue that I am seeing is a return type mismatch between getch and get_wch or getkey. Both of get_wch() and getkey() returns a PyObject *. Maybe we can change _curses_window_getch_impl to return a PyLong pointer similar to get_wch_impl and getkey_impl? This would make sure we are always dealing with the same return type.

  4. picnixz commented on May 19, 2025

    @picnixz
    MemberAuthor

    It's not a mismatch. It's handled by Argument Clinic so it's fine.

  5. picnixz commented on May 19, 2025

    @picnixz
    MemberAuthor

    But I'll probably handle it as part of the rest of the cleanup

  6. added a commit that references this issue on May 27, 2025
  7. added a commit that references this issue on May 27, 2025
  8. added 4 commits that reference this issue on May 27, 2025
  9. added 2 commits that reference this issue on Jul 12, 2025
  10. added 2 commits that reference this issue on Aug 4, 2025
  11. added 2 commits that reference this issue on Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions