I have submitted two patches for the subprocess module against cvs HEAD. The first notifies the user of a common mistake and the second adds an IHMO very important utility function. I'd consider the first to be a bug fix and the second a new feature. However a rather nice new feature ;-) ------------------------------------------------------------ [ 1071755 ] raise error for common mistake with subprocess http://python.org/sf/1071755 ------------------------------------------------------------ subprocess has a very easy to mistake error in it - forgetting to pass the command as a list. Eg
import subprocess subprocess.call("ls") BaseHTTPServer.py dummy_threading.py pickletools.py socket.py Bastion.py email pipes.py sre.py [...] dummy_thread.py pickle.pyc sndhdr.py zipfile.py 0 subprocess.call("ls", "-l") BaseHTTPServer.py dummy_threading.py pickletools.py socket.py Bastion.py email pipes.py sre.py [...] dummy_thread.py pickle.pyc sndhdr.py zipfile.py 0
# Note no error, warning or anything, but no "ls -l" either And with the patch...
subprocess.call("ls", "-l") Traceback (most recent call last): File "<stdin>", line 1, in ? File "subprocess.py", line 428, in call return Popen(*args, **kwargs).wait() File "subprocess.py", line 508, in __init__ raise TypeError("bufsize must be an integer - " TypeError: bufsize must be an integer - did you forget to pass your arguments in a list?
------------------------------------------------------------ [ 1071764 ] a new subprocess.call which raises an error on non-zero rc http://python.org/sf/1071764 ------------------------------------------------------------ The attached patch introduces a 3rd utility function - xcall() to the subprocess module. This function acts just like call but raises errors if the command had a non-zero return code. This saves writing if call(...): raise OSError(...) It is most useful for shell script replacement programming. Checking the return codes of commands called is often forgotten in shell programming. When you've moved up to python because shell is too limiting (usually about 10 lines of shell in my case ;-) you want to make sure that all your commands work so you write robust code. I consider raising an exception to be much more pythonic than checking a return code (ie "Errors should never pass silently" from Zen of Python) Eg # An easy to miss error
subprocess.call(["mkdir", "a/b"]) mkdir: cannot create directory `a/b': No such file or directory 1 # user forgot to check non-zero return code
# becomes an impossible to miss exception
subprocess.xcall(["mkdir", "a/b"]) mkdir: cannot create directory `a/b': No such file or directory Traceback (most recent call last): File "<stdin>", line 1, in ? File "subprocess.py", line 462, in xcall raise CalledProcessError(rc, "Command %s returned non zero exit status" % args[0]) subprocess.CalledProcessError: [Errno 1] Command ['mkdir', 'a/b'] returned non zero exit status
See patch for more! Its been tested under python 2.3 on windows and
linux.
--
Nick Craig-Wood