Atsuo Ishimoto added the comment:

> Benjamin Peterson added the comment:
> 
> The OP probably wants something like the Linux-specific signalfd() syscall.
Yes.

Long explanation:

I have an console text editor written in 
Python/curses(http://kaaedit.github.io/).

This editor didn't work with Python 3.5 because select.select() stop raising 
InterruptedError.

Following is sample code to reproduce. This code displays size of terminal. If 
you resize your terminal, screen is updated and new size is displayed.

---------------------------

import curses, select, sys

def main(stdscr):
    i=0
    while True:
        y, x = stdscr.getmaxyx()
        stdscr.addstr(i % 10, 0, "%d x:%d y:%d" % (i, x, y))
        i+=1
        stdscr.refresh()
        try:
            s=select.select([sys.stdin], [], [])   # wait for user input and 
some sockets.
        except InterruptedError:
            stdscr.addstr(i % 10, 0, "%d InterruptedError" % i)
            i+=1
            continue
        try:
            c=stdscr.get_wch()
        except curses.error:
            stdscr.addstr(i % 10, 0, "%d curses.error" % i)
            i+=1
            continue
        if c == 'q':
            break

curses.wrapper(main)

---------------------------

Resizing terminal generates SIGIWNCH signal. In Python 3.4, select.select() 
raises InterruptedError when the signal sent. Also, Ncurses library catches the 
signal and update internal data to reflect new terminal size.

To detect resizing in Python 3.5, I had to set signal handler for SIGWINCH as 
following sample. 

---------------
import curses, select, sys, signal, os

rfd, wfd = os.pipe()
os.set_blocking(wfd, False)

def f(*args): pass
signal.signal(signal.SIGWINCH, f)
signal.set_wakeup_fd(wfd)

def main(stdscr):
    i=0
    while True:
        y, x = stdscr.getmaxyx()
        stdscr.addstr(i, 0, "%d x:%d y:%d" % (i, x, y))
        i+=1
        stdscr.refresh()
        try:
            s=select.select([sys.stdin, rfd], [], [])
        except InterruptedError:
            stdscr.addstr(i, 0, "%d InterruptedError" % i)
            i+=1
            continue
        try:
            c=stdscr.get_wch()
        except curses.error:
            stdscr.addstr(i, 0, "%d curses.error" % i)
            i+=1
            continue
        if c == 'q':
            break

curses.wrapper(main)
-------------

This code doesn't display updated size of terminal because SIGWINCH signal is 
not sent to nurses library. I have to call curses.resizeterm() manually to tell 
new terminal size to nurses.

I don't know this is common situation or not, but In general, it is not safe to 
set signal handler when the signal is used by third-party library.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25482>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to