2016-06-24 2:46 GMT+02:00 Donald Stufft <donald@stufft.io>:
I think the biggest argument to blocking is that there really exist two sort of situations that blocking can happen in:
* It blocks for a tiny amount (maybe <1s) and nobody ever notices and people feel like things “just work”. * It blocks for a long amount of time (possibly forever depending on where in the boot sequence Python is being used) and it hangs for a long time (or forever).
In the second case I think it’s pretty obvious that an exception is better than hanging forever, but in the first case an exception might actually cause people to go out of their way to do something bad to “stop the pain”. My personal preference is waffling back and forth between them based on which of the two above I feel are more likely to occur in practice.
Maybe I'm wrong, but *starting* to raise BlockingIOError looks like the opposite direction taken by Python with EINTR (PEP 475). We had to add try/except InterruptedError in many modules (asyncio, asyncio, io, multiprocessing, selectors, socket, socketserver, subprocess), but it was decided to fix the root issue: retry the syscal if it failed with EINTR directly in the C code, so you never have to handle InterruptedError at the Python level anymore. For EINTR, it was decided that the common case is to restart automatically the syscall. The rare case is when the user expects that the program is really interrupted, and this case requires to raise an exception in the signal handler. FYI The PEP 475 has a minor incompatible change: programs relying on EINTR with a signal handler not raising a Python exceptions were broken by this change. They had to modify their signal handler to raise an exception. I recall to have to fix *one* library and then..... nothing, nobody complained. I was suprised, I expected that the "rare" case was more common than that :-) To come back to urandom: the common case is to wait for random, the exception is to want to be notified and run special code. Maybe it's not worth to have to modify all libraries and applications for the exception, but maybe add a special function for the exception. In a different thread, I proposed to expose os.getrandom() even if my PEP (blocking os.urandom) is accepted, because getrandom() provides features not available only using os.urandom(). What do you think of making os.urandom() blocking on Linux but also add os.getrandom() to handle the exceptional case? Victor