I am using Python 3.7 on a Debian Linux 9 box with the standard readline and curses modules. The following code should output \'True\' when run inside an xterm and the xterm is
In a quick check with strace, I can see that something resets the SIGWINCH
handler back to SIG_DFL
(no action) after ncurses sets its handler for SIGWINCH
. The symbol table of readline has these relevant entrypoints:
_rl_block_sigwinch
_rl_redisplay_after_sigwinch
_rl_release_sigwinch
_rl_sigwinch_resize_terminal
rl_catch_sigwinch
The documentation for readline notes
o A new variable, rl_catch_sigwinch, is available to application
writers to indicate to readline whether or not it should install its
own signal handler for SIGWINCH, which will chain to the calling
applications's SIGWINCH handler, if one is installed;
However, reading the source for libpython3.5, it appears that the developer did not take that into account:
/* Helper to initialize GNU readline properly. */
static void
setup_readline(readlinestate *mod_state)
{
...
rl_readline_name = "python";
/* Force rebind of TAB to insert-tab */
rl_bind_key('\t', rl_insert);
/* Bind both ESC-TAB and ESC-ESC to the completion function */
rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
#ifdef HAVE_RL_RESIZE_TERMINAL
/* Set up signal handler for window resize */
sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
#endif
This change in 2016 appears to be related to the problem you're seeing (offhand, it looks like a new problem was introduced without solving the old one). If the signal-handler added for readline doesn't chain over to the one in ncurses, then the latter's no longer used and ncurses cannot return KEY_RESIZE
. Also—if readline sets up its handler first, ncurses won't set up its handler.
The latter seems to be the case: the import readline
calls the module initialization which sets up a signal handler. The ncurses signal handler is initialized when the Python curses wrapper calls initscr
. That's not done in PyInit__curses
(the function called on import curses
) because that would clear the screen. Alternatively, ncurses would initialize its signal handler if newterm
was called (which would not clear the screen), but Python doesn't do that.
You could work around this by loading the ncurses (or ncursesw!) library and calling newterm
followed by endwin
, doing that before the import
statements. That seems like a lot of work. I'd recommend opening a bug report.
For reference: