summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorPeter Astrand <astrand@lysator.liu.se>2005-01-01 09:36:35 (GMT)
committerPeter Astrand <astrand@lysator.liu.se>2005-01-01 09:36:35 (GMT)
commit454f76711c14f0a55119601bfe56a1ab5d2c0e04 (patch)
treef81416ce45244479ab525018c0b2078f8d591946 /Lib
parented2dbe3f3344038dee8389f0ade335da1b3b559a (diff)
downloadcpython-454f76711c14f0a55119601bfe56a1ab5d2c0e04.zip
cpython-454f76711c14f0a55119601bfe56a1ab5d2c0e04.tar.gz
cpython-454f76711c14f0a55119601bfe56a1ab5d2c0e04.tar.bz2
New subprocess utility function: check_call. Closes #1071764.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/subprocess.py40
-rw-r--r--Lib/test/test_subprocess.py16
2 files changed, 55 insertions, 1 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 40b04fe..da0c31b 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -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
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index b26d40c..52f4d47 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -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()