Commit 725f365c authored by Denis Bilenko's avatar Denis Bilenko

subprocess.py: add call(), check_call(), check_output()

parent 17e3b6ab
......@@ -7,7 +7,6 @@ import signal
import traceback
from gevent.event import Event
from gevent.hub import get_hub
from gevent.select import select
from gevent.fileobject import FileObject
from gevent.greenlet import Greenlet, joinall
spawn = Greenlet.spawn
......@@ -15,15 +14,15 @@ __subprocess__ = __import__('subprocess')
# Standard functions and classes that this module re-implements in a gevent-aware way.
__implements__ = ['Popen']
__implements__ = ['Popen',
'call',
'check_call',
'check_output']
# Standard functions and classes that this module re-imports.
__imports__ = ['PIPE',
'STDOUT',
'call',
'check_call',
'check_output',
'CalledProcessError',
# Windows:
'CREATE_NEW_CONSOLE',
......@@ -40,7 +39,6 @@ __extra__ = ['MAXFD',
'_eintr_retry_call',
'STARTUPINFO',
'pywintypes',
'_PIPE_BUF',
'list2cmdline',
'_subprocess',
# Python 2.5 does not have _subprocess, so we don't use it
......@@ -98,10 +96,68 @@ else:
import fcntl
import pickle
# When select or poll has indicated that the file is writable,
# we can write up to _PIPE_BUF bytes without risk of blocking.
# POSIX defines PIPE_BUF as >= 512.
_PIPE_BUF = getattr(select, 'PIPE_BUF', 512)
def call(*popenargs, **kwargs):
"""Run command with arguments. Wait for command to complete, then
return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:
retcode = call(["ls", "-l"])
"""
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 returncode attribute.
The arguments are the same as for the Popen constructor. Example:
check_call(["ls", "-l"])
"""
retcode = call(*popenargs, **kwargs)
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise CalledProcessError(retcode, cmd)
return 0
def check_output(*popenargs, **kwargs):
r"""Run command with arguments and return its output as a byte string.
If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
The arguments are the same as for the Popen constructor. Example:
>>> check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
The stdout argument is not allowed as it is used internally.
To capture standard error in the result, use stderr=STDOUT.
>>> check_output(["/bin/sh", "-c",
... "ls -l non_existent_file ; exit 0"],
... stderr=STDOUT)
'ls: non_existent_file: No such file or directory\n'
"""
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = Popen(stdout=PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise CalledProcessError(retcode, cmd, output=output)
return output
class Popen(object):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment