[Python-ideas] Adding a subprocess.CompletedProcess class

Thomas Kluyver thomas at kluyver.me.uk
Wed Jan 28 01:43:31 CET 2015


The subprocess module provides some nice tools to control the details of
running a process, but it's still rather awkward for common use cases where
you want to execute a command in one go.

* There are three high-level functions: call, check_call and check_output,
which all do very similar things with different return/raise behaviours
* Their naming is not very clear (check_output doesn't check the output, it
checks the return code and captures the output)
* You can't use any of them if you want stdout and stderr separately.
* You can get stdout and returncode from check_output, but it's not exactly
obvious:

try:
    stdout = check_output(...)
    returncode = 0
except CalledProcessError as e:
    stdout = e.output
    returncode = e.returncode

I think that what these are lacking is a good way to represent a process
that has already finished (as opposed to Popen, which is mostly designed to
handle a running process). So I would:

1. Add a CompletedProcess class:
* Attributes stdout and stderr are bytes if the relevant stream was piped,
None otherwise, like the return value of Popen.communicate()
* Attribute returncode is the exit status
* ? Attribute cmd is the list of arguments the process ran with (not sure
if this should be there or not)
* Method cp.check_returncode() raises CalledProcessError if returncode !=
0, inspired by requests' Response.raise_for_status()

2. Add a run() function - like call/check_call/check_output, but returns a
CompletedProcess instance

3. Deprecate call/check_call/check_output, but leave them around
indefinitely, since lots of existing code relies on them.

Thanks,
Thomas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150127/04dcbfa2/attachment.html>


More information about the Python-ideas mailing list