At the end of August, I sent the PEP 475 which I wrote with Charles-François Natali:
Antoine Pitrou wrote " I'm +1 on the whole PEP" and R. David Murray wrote "Personally, I really want Python to handle EINTR for me".
What's the next step? Who wants to handle this PEP? Guido? Antoine?
I will try to answer to questions if previous answers were not enough.
Antoine Pitrou wrote:
On Unix, the ``asyncio`` module uses the wakeup file descriptor to wake up its event loop.
How about Windows?
I modified signal.set_wakeup_fd() in Python 3.5 to support a socket on Windows. So it becomes possible to support signals with signal.set_wakeup_fd() on Windows (for SelectorEventLoop and ProactorEventLoop):
Antoine Pitrou wrote:
Some signals are not interesting and should not interrupt the the application. There are two options to only interrupt an application on some signals:
- Raise an exception in the signal handler, like ``KeyboardInterrupt`` for ``SIGINT``
- Use a I/O multiplexing function like ``select()`` with the Python signal "wakeup" file descriptor: see the function ``signal.set_wakeup_fd()``.
This section looks a bit incomplete. Some calls such as os.read() or os.write() will (should) return a partial result when interrupted and they already handled >0 bytes. Perhaps other functions have a similar behaviour?
In Python 3.4, os.read() is dummy: it only calls the C function read() once.
With the PEP 475, read() is only called again on EINTR if the signal handler did not raise an exception. When read() returns EINTR, there is "partial read", the read did not start yet.
So I don't understand what should be added to the PEP. There is no specific change.
Matthew Woodcraft wrote:
In any case I think PEP 475 should be explaining what is going to happen to signal.siginterrupt(). Will setting flag=True be supported? If so, will doing so change the behaviour of those parts of the stdlib which have already been modified to retry after EINTR?
In Python 3.4, signal.signal() calls siginterrupt(signum, True): syscalls raise InterruptedError when interrupted by a signal. Calling explicitly signal.siginterrupt(signum, True) doesn't change anything.
In Python 3.4, signal.siginterrupt(signum, False) reduces the cases when InterruptedError is raised, but they are still cases when InterruptedError is raised. The exact behaviour probably depends on the operating system or even the version of the operating system. It's better to not rely on siginterrupt(False) to write portable code in Python 3.4.
With the PEP, signal.siginterrupt(signum, False) is still supported. The PEP doesn't change the behaviour when the syscall is directly restarted by the C library. If the function returns EINTR, the interrupted syscall is retried if the signal handler didn't raise an exception.
The main problem of siginterrupt(False) is that the Python signal handler is *not* called if the C library directly retries the interrupted syscall.
Note: if signals are blocked, the C signal handlers are not called, so the PEP doesn't change the behaviour neither.
I think that the stdlib should not handle InterruptedError exception anymore in the Python code, to simplify the code.
I modified the PEP to mention that: https://hg.python.org/peps/rev/627fefe0394f