why does popen2 silently ignore IOError?

Donn Cave donn at u.washington.edu
Wed Feb 20 15:11:45 EST 2002


Quoth Graham Guttocks <graham_guttocks at yahoo.co.nz>:
| Can anyone explain why the popen2 module silently ignores an IOError? 
| I'm trying to use it to send mail instead of os.popen() to avoid 
| invoking /bin/sh.  
|
| If all the command-line arguments are proper, things work fine, but if 
| I open a bogus command-line, popen2 doesn't complain, neither during 
| the write, nor close.  Take the following simple example: 

Where's the IOError?

popen2's behavior here is more or less in line with system() and popen(),
in the general sense that it does not raise an exception in the case of
a non-zero exit from the child process.  I agree that it's a defect, the
kind of thing we hope to get away from when we choose to write Python.
But as a practical matter, process exit statuses aren't as useful as the
error codes you get from system functions, for example.  I personally
prefer to get an exception, with value from stderr output, but it's
debatable whether that would have been a good default for system & popen.
And popen would have to be redesigned anyway, instead of file objects it
would have to return special I/O objects with the ability to monitor their
process.

What does this have to do with failed execs?  By the time an exec fails
like that, it's already in a fork, and the only way it can get the news
back to the caller is in the fork's exit status, and there isn't any way
to make that number say "exec failed", without some ambiguity.  There may
be some way to get that information - for example, if you wanted to go to
the trouble to create an extra pipe for internal use, the fork could write
a message to the pipe indicating exec failure.  Obviously no one has done
this in popen2, though.

popen is actually a bit better than popen2 here, though, inasmuch as when
you close the file object you get a special return value with the exit
status.  To get this value with popen2, you need to use the Popen3 class
and call its wait() member function.

	Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list