Skip to content

Instantly share code, notes, and snippets.

@bsolomon1124
Created March 5, 2020 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsolomon1124/bf30ad662ea6567900ed7ec8c7567ab8 to your computer and use it in GitHub Desktop.
Save bsolomon1124/bf30ad662ea6567900ed7ec8c7567ab8 to your computer and use it in GitHub Desktop.
Backport of Python 3.8 subprocess for 2.7 with improvements
#!/usr/bin/env python2
"""Backport of Python 3.8 subprocess for 2.7 with improvements."""
from __future__ import print_function
__all__ = ("run",)
from subprocess import PIPE, Popen as _Popen27
# TODO: check bufsize arg
class Popen(_Popen27):
def __enter__(self):
return self
def __exit__(self, exc_type, value, traceback):
if self.stdout:
self.stdout.close()
if self.stderr:
self.stderr.close()
try:
if self.stdin:
self.stdin.close()
finally:
self.wait()
def run(args, input=None, check=True, universal_newlines=True):
with Popen(args, stdout=PIPE, stderr=PIPE, universal_newlines=universal_newlines) as proc:
try:
stdoutdata, stderrdata = proc.communicate(input=input)
except:
proc.kill()
retcode = proc.poll()
if check and retcode:
raise CalledProcessError(retcode, args, output=stdoutdata, stderr=stderrdata)
return CompletedProcess(args, retcode, stdoutdata, stderrdata)
class CompletedProcess(object):
def __init__(self, args, returncode, stdout=None, stderr=None):
self.args = args
self.returncode = returncode
self.stdout = stdout
self.stderr = stderr
def check_returncode(self):
if self.returncode:
raise CalledProcessError(self.returncode, self.args, self.stdout, self.stderr)
def __repr__(self):
return "{}({})".format(type(self).__name__, 'returncode={!r}'.format(self.returncode))
class CalledProcessError(Exception):
def __init__(self, returncode, cmd, output=None, stderr=None):
self.returncode = returncode
self.cmd = cmd
self.output = output
self.stderr = stderr
def __str__(self):
return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
if __name__ == "__main__":
out = run(['ls', '-la'])
print("stdout", out.stdout)
print("stderr", out.stderr)
print("returncode", out.returncode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment