Created
March 5, 2020 22:06
-
-
Save bsolomon1124/bf30ad662ea6567900ed7ec8c7567ab8 to your computer and use it in GitHub Desktop.
Backport of Python 3.8 subprocess for 2.7 with improvements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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