Issue25482
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2015-10-26 11:34 by ishimoto, last changed 2022-04-11 14:58 by admin.
Messages (12) | |||
---|---|---|---|
msg253468 - (view) | Author: Atsuo Ishimoto (ishimoto) * | Date: 2015-10-26 11:34 | |
I expect following code prints '\x1c' when I resize terminal window on Linix/Mac terminal. -------------------------------- import select, os, signal rfd, wfd = os.pipe() os.set_blocking(wfd, False) signal.set_wakeup_fd(wfd) select.select([rfd], [], []) print(os.read(rfd, 2)) -------------------------------- Resizing terminal window make SIGWINCH signal sent to Python process. But nothing written to fd I specified to set_wakeup_fd(). I checked Modules/signalmodule.c and found I should assign signal handler for the signal I want to wakeup fd. So following code works as I expected. -------------------------------- import select, os, signal rfd, wfd = os.pipe() os.set_blocking(wfd, False) signal.set_wakeup_fd(wfd) signal.signal(signal.SIGWINCH, lambda *args:0) select.select([rfd], [], []) print(os.read(rfd, 2)) -------------------------------- Is this an expected behavior of signal.set_wakeup_fd()? |
|||
msg253517 - (view) | Author: Benjamin Peterson (benjamin.peterson) * | Date: 2015-10-27 04:49 | |
Yes, you need to tell the kernel to not ignore SIGWINCH automatically for you. |
|||
msg253520 - (view) | Author: Atsuo Ishimoto (ishimoto) * | Date: 2015-10-27 05:27 | |
Okay, so I think this needed to be documented in signal.set_wakeup_fd(). IMO this reduces usefulness of set_wakeup_fd(). If I need to install custom handler by my self, I can write to fd in my own custom handler. And, installing custom handler omits existing handler, but we can not execute existing signal handler from python script. In my real-world case, SIGWINCH signal does not delivered to curses library. pep-475(https://www.python.org/dev/peps/pep-0475/#backward-compatibility) claims that "For applications using event loops, signal.set_wakeup_fd() is the recommanded option to handle signals. " But I think side effect of signal.set_wakeup_fd() is lager than pep-475 authors expected. |
|||
msg253602 - (view) | Author: STINNER Victor (vstinner) * | Date: 2015-10-28 14:54 | |
> IMO this reduces usefulness of set_wakeup_fd(). (...) Sorry, I don't understand your use case. Could you elaborate. What do you need? -- According to the GNU libc doc, the signal SIGWINCH is *ignored* by default: "Window size change. This is generated on some systems (including GNU) when the terminal driver’s record of the number of rows and columns on the screen is changed. The default action is to ignore it." https://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html For signal.set_wakeup_fd() I agree that the doc can be enhanced. It's not explicit that only signals with a *Python* signal handler (at least, a signal handler registered by signal.signal) write into the "wakeup FD". |
|||
msg253657 - (view) | Author: Benjamin Peterson (benjamin.peterson) * | Date: 2015-10-29 06:17 | |
The OP probably wants something like the Linux-specific signalfd() syscall. |
|||
msg253677 - (view) | Author: Atsuo Ishimoto (ishimoto) * | Date: 2015-10-29 14:44 | |
> 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. |
|||
msg253711 - (view) | Author: STINNER Victor (vstinner) * | Date: 2015-10-30 03:14 | |
It's very easy to get the same behaviour on Python 3.4 (without PEP 475) and Python 3.5 (with PEP 475). Just add the following code at the top of your example: ---- import signal def sighandler(signum, frame): raise InterruptedError signal.signal(signal.SIGWINCH, sighandler) --- You can use any Python exception, not only InterruptedError. PEP 475 only changes the behaviour on signals with an handler which doesn't raise an exception. |
|||
msg253712 - (view) | Author: Atsuo Ishimoto (ishimoto) * | Date: 2015-10-30 03:33 | |
Thank you for good sample. This should be written in PEP 475. But installing new signal handler can cause different behavior. As in my previous example, if other 3rd party libraries(ncurses in my case) need to handle the signal, signal is consumed by Python handler and not delivered to the library. |
|||
msg253724 - (view) | Author: STINNER Victor (vstinner) * | Date: 2015-10-30 10:02 | |
> As in my previous example, if other 3rd party libraries(ncurses in my case) need to handle the signal, signal is consumed by Python handler and not delivered to the library. In the Python signal handler, can't you call the ncurses function that should be called when the terminal is resized? |
|||
msg253727 - (view) | Author: Atsuo Ishimoto (ishimoto) * | Date: 2015-10-30 11:13 | |
Yes, I can. So, for my custom text editor, problem have solved already. But I still think it is desirable for Python to have something like signalfd(), because not all functions used in the signal handler of third party library can be called from user's Python script in general. |
|||
msg253728 - (view) | Author: STINNER Victor (vstinner) * | Date: 2015-10-30 11:29 | |
Atsuo Ishimoto added the comment: > But I still think it is desirable for Python to have something like signalfd(), because not all functions used in the signal handler of third party library can be called from user's Python script in general. I don't think that you can use signalfd() in your case. When you use signalfd(), signals must be blocked, so the signal handlers are *not* called (not the Python signal handler, not the C signal handler, no signal handler for the masked signals). |
|||
msg253729 - (view) | Author: Atsuo Ishimoto (ishimoto) * | Date: 2015-10-30 11:39 | |
Ah, I didn't know it. Thank you for clarification. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:23 | admin | set | github: 69668 |
2015-10-30 11:39:35 | ishimoto | set | messages: + msg253729 |
2015-10-30 11:29:12 | vstinner | set | messages: + msg253728 |
2015-10-30 11:13:06 | ishimoto | set | messages: + msg253727 |
2015-10-30 10:02:26 | vstinner | set | messages: + msg253724 |
2015-10-30 03:33:43 | ishimoto | set | messages: + msg253712 |
2015-10-30 03:14:07 | vstinner | set | messages: + msg253711 |
2015-10-29 14:44:24 | ishimoto | set | messages: + msg253677 |
2015-10-29 06:17:25 | benjamin.peterson | set | messages: + msg253657 |
2015-10-28 14:54:44 | vstinner | set | messages: + msg253602 |
2015-10-28 10:58:37 | berker.peksag | set | nosy:
+ vstinner |
2015-10-27 05:27:45 | ishimoto | set | status: closed -> open assignee: docs@python components: + Documentation, - Library (Lib) nosy: + docs@python messages: + msg253520 resolution: not a bug -> |
2015-10-27 04:49:56 | benjamin.peterson | set | status: open -> closed nosy: + benjamin.peterson messages: + msg253517 resolution: not a bug |
2015-10-26 11:34:56 | ishimoto | create |