]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
New subprocess utility function: check_call. Closes #1071764.
authorPeter Astrand <astrand@lysator.liu.se>
Sat, 1 Jan 2005 09:36:35 +0000 (09:36 +0000)
committerPeter Astrand <astrand@lysator.liu.se>
Sat, 1 Jan 2005 09:36:35 +0000 (09:36 +0000)
Doc/lib/libsubprocess.tex
Lib/subprocess.py
Lib/test/test_subprocess.py

index 308c1dd40f9bfc9770629d81e268facf2d3efada..5a2a835f1e69253af9f3f0f1e1da466344c09312 100644 (file)
@@ -120,7 +120,7 @@ process.  (Windows only)
 
 \subsubsection{Convenience Functions}
 
-This module also defines one shortcut function:
+This module also defines two shortcut functions:
 
 \begin{funcdesc}{call}{*popenargs, **kwargs}
 Run command with arguments.  Wait for command to complete, then
@@ -133,6 +133,18 @@ The arguments are the same as for the Popen constructor.  Example:
 \end{verbatim}
 \end{funcdesc}
 
+\begin{funcdesc}{check_call}{*popenargs, **kwargs}
+Run command with arguments.  Wait for command to complete. If the exit
+code was zero then return, otherwise raise CalledProcessError.  The
+CalledProcessError object will have the return code in the
+\member{errno} attribute.
+
+The arguments are the same as for the Popen constructor.  Example:
+
+\begin{verbatim}
+    check_call(["ls", "-l"])
+\end{verbatim}
+\end{funcdesc}
 
 \subsubsection{Exceptions}
 
@@ -149,6 +161,10 @@ should prepare for \exception{OSError} exceptions.
 A \exception{ValueError} will be raised if \class{Popen} is called
 with invalid arguments.
 
+check_call() will raise \exception{CalledProcessError}, which is a
+subclass of \exception{OSError}, if the called process returns a
+non-zero return code.
+
 
 \subsubsection{Security}
 
index 40b04fe39ffdf1f3582d53d3b72909bc51bdba89..da0c31b6c93d9d5248238a4f881645b16c5c5ef6 100644 (file)
@@ -133,6 +133,15 @@ call(*popenargs, **kwargs):
 
     retcode = call(["ls", "-l"])
 
+check_call(*popenargs, **kwargs):
+    Run command with arguments.  Wait for command to complete.  If the
+    exit code was zero then return, otherwise raise
+    CalledProcessError.  The CalledProcessError object will have the
+    return code in the errno attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    check_call(["ls", "-l"])
 
 Exceptions
 ----------
@@ -148,6 +157,9 @@ should prepare for OSErrors.
 
 A ValueError will be raised if Popen is called with invalid arguments.
 
+check_call() will raise CalledProcessError, which is a subclass of
+OSError, if the called process returns a non-zero return code.
+
 
 Security
 --------
@@ -363,6 +375,13 @@ import os
 import types
 import traceback
 
+# Exception classes used by this module.
+class CalledProcessError(OSError):
+    """This exception is raised when a process run by check_call() returns
+    a non-zero exit status.  The exit status will be stored in the
+    errno attribute.  This exception is a subclass of
+    OSError."""
+
 if mswindows:
     import threading
     import msvcrt
@@ -393,7 +412,7 @@ else:
     import fcntl
     import pickle
 
-__all__ = ["Popen", "PIPE", "STDOUT", "call"]
+__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"]
 
 try:
     MAXFD = os.sysconf("SC_OPEN_MAX")
@@ -428,6 +447,25 @@ def call(*popenargs, **kwargs):
     return Popen(*popenargs, **kwargs).wait()
 
 
+def check_call(*popenargs, **kwargs):
+    """Run command with arguments.  Wait for command to complete.  If
+    the exit code was zero then return, otherwise raise
+    CalledProcessError.  The CalledProcessError object will have the
+    return code in the errno attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    check_call(["ls", "-l"])
+    """
+    retcode = call(*popenargs, **kwargs)
+    cmd = kwargs.get("args")
+    if cmd is None:
+        cmd = popenargs[0]
+    if retcode:
+        raise CalledProcessError(retcode, "Command %s returned non-zero exit status" % cmd)
+    return retcode
+
+
 def list2cmdline(seq):
     """
     Translate a sequence of arguments into a command line
index b26d40cb29d4f65da34b7d046c7d9daeeb33eaa0..52f4d4711d25ac063d539197b663f37f0d3cf75d 100644 (file)
@@ -44,6 +44,22 @@ class ProcessTestCase(unittest.TestCase):
                               "import sys; sys.exit(47)"])
         self.assertEqual(rc, 47)
 
+    def test_check_call_zero(self):
+        # check_call() function with zero return code
+        rc = subprocess.check_call([sys.executable, "-c",
+                                    "import sys; sys.exit(0)"])
+        self.assertEqual(rc, 0)
+
+    def test_check_call_nonzero(self):
+        # check_call() function with non-zero return code
+        try:
+            subprocess.check_call([sys.executable, "-c",
+                                   "import sys; sys.exit(47)"])
+        except subprocess.CalledProcessError, e:
+            self.assertEqual(e.errno, 47)
+        else:
+            self.fail("Expected CalledProcessError")
+
     def test_call_kwargs(self):
         # call() function with keyword args
         newenv = os.environ.copy()