
On Jul 22, 2010, at 12:00 AM, Stephen J. Turnbull wrote:
My understanding of OSError is that the OS is saying "sorry, what you tried to do is perfectly reasonable under some circumstances, but you can't do that now." ENOMEM, EPERM, ENOENT etc fit this model.
RuntimeError OTOH is basically saying "You should know better than to try that!" EINVAL fits this model.
That is not my understanding of OSError at all, especially given that I have seen plenty of OSErrors that have EINVAL set by various things. OSError's docstring specifically says "OS system call failed.", and that's the way I've already understood it: you made a syscall and got some kind of error. Python _mostly_ avoids classifying OSErrors into different exception types in other APIs. The selection of RuntimeError in this particular case seems somewhat random and ad-hoc, given that out-of-range signal values give ValueError while SIGKILL and SIGSTOP give RuntimeError. The RuntimeError's args start with "22" (which I assume is supposed to mean "EINVAL") but it doesn't have an 'errno' attribute as an OSError would. The ValueError doesn't relate to an errno at all. Nowhere does the documentation say "raises OSError or ValueError or TypeError or RuntimeError whose args[0] may be an errno". To be clear, this particular area doesn't bother me. I've been dealing with weird and puzzling signal-handling issues in Python for years and years and this dusty corner of the code has never come up. I did want to reply to this particular message, though, because I *would* eventually like the exception hierarchy raised by certain stdlib functions to be more thoroughly documented and coherent, but a prerequisite to that is to avoid rationalizing the random potpourri of exception types that certain parts of the stdlib emit. I think signal.signal is one such part.