Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
subprocess.py144 linesDownload Raw Back to green
1import errno2import sys3from types import FunctionType4 5import eventlet6from eventlet import greenio7from eventlet import patcher8from eventlet.green import select, threading, time9import six10 11 12__patched__ = ['call', 'check_call', 'Popen']13to_patch = [('select', select), ('threading', threading), ('time', time)]14 15if sys.version_info > (3, 4):16    from eventlet.green import selectors17    to_patch.append(('selectors', selectors))18 19patcher.inject('subprocess', globals(), *to_patch)20subprocess_orig = patcher.original("subprocess")21subprocess_imported = sys.modules.get('subprocess', subprocess_orig)22mswindows = sys.platform == "win32"23 24 25if getattr(subprocess_orig, 'TimeoutExpired', None) is None:26    # Backported from Python 3.3.27    # https://bitbucket.org/eventlet/eventlet/issue/8928    class TimeoutExpired(Exception):29        """This exception is raised when the timeout expires while waiting for30        a child process.31        """32 33        def __init__(self, cmd, timeout, output=None):34            self.cmd = cmd35            self.timeout = timeout36            self.output = output37 38        def __str__(self):39            return ("Command '%s' timed out after %s seconds" %40                    (self.cmd, self.timeout))41else:42    TimeoutExpired = subprocess_imported.TimeoutExpired43 44 45# This is the meat of this module, the green version of Popen.46class Popen(subprocess_orig.Popen):47    """eventlet-friendly version of subprocess.Popen"""48    # We do not believe that Windows pipes support non-blocking I/O. At least,49    # the Python file objects stored on our base-class object have no50    # setblocking() method, and the Python fcntl module doesn't exist on51    # Windows. (see eventlet.greenio.set_nonblocking()) As the sole purpose of52    # this __init__() override is to wrap the pipes for eventlet-friendly53    # non-blocking I/O, don't even bother overriding it on Windows.54    if not mswindows:55        def __init__(self, args, bufsize=0, *argss, **kwds):56            self.args = args57            # Forward the call to base-class constructor58            subprocess_orig.Popen.__init__(self, args, 0, *argss, **kwds)59            # Now wrap the pipes, if any. This logic is loosely borrowed from60            # eventlet.processes.Process.run() method.61            for attr in "stdin", "stdout", "stderr":62                pipe = getattr(self, attr)63                if pipe is not None and type(pipe) != greenio.GreenPipe:64                    # https://github.com/eventlet/eventlet/issues/24365                    # AttributeError: '_io.TextIOWrapper' object has no attribute 'mode'66                    mode = getattr(pipe, 'mode', '')67                    if not mode:68                        if pipe.readable():69                            mode += 'r'70                        if pipe.writable():71                            mode += 'w'72                        # ValueError: can't have unbuffered text I/O73                        if bufsize == 0:74                            bufsize = -175                    wrapped_pipe = greenio.GreenPipe(pipe, mode, bufsize)76                    setattr(self, attr, wrapped_pipe)77        __init__.__doc__ = subprocess_orig.Popen.__init__.__doc__78 79    def wait(self, timeout=None, check_interval=0.01):80        # Instead of a blocking OS call, this version of wait() uses logic81        # borrowed from the eventlet 0.2 processes.Process.wait() method.82        if timeout is not None:83            endtime = time.time() + timeout84        try:85            while True:86                status = self.poll()87                if status is not None:88                    return status89                if timeout is not None and time.time() > endtime:90                    raise TimeoutExpired(self.args, timeout)91                eventlet.sleep(check_interval)92        except OSError as e:93            if e.errno == errno.ECHILD:94                # no child process, this happens if the child process95                # already died and has been cleaned up96                return -197            else:98                raise99    wait.__doc__ = subprocess_orig.Popen.wait.__doc__100 101    if not mswindows:102        # don't want to rewrite the original _communicate() method, we103        # just want a version that uses eventlet.green.select.select()104        # instead of select.select().105        _communicate = FunctionType(106            six.get_function_code(six.get_unbound_function(107                subprocess_orig.Popen._communicate)),108            globals())109        try:110            _communicate_with_select = FunctionType(111                six.get_function_code(six.get_unbound_function(112                    subprocess_orig.Popen._communicate_with_select)),113                globals())114            _communicate_with_poll = FunctionType(115                six.get_function_code(six.get_unbound_function(116                    subprocess_orig.Popen._communicate_with_poll)),117                globals())118        except AttributeError:119            pass120 121 122# Borrow subprocess.call() and check_call(), but patch them so they reference123# OUR Popen class rather than subprocess.Popen.124def patched_function(function):125    new_function = FunctionType(six.get_function_code(function), globals())126    if six.PY3:127        new_function.__kwdefaults__ = function.__kwdefaults__128    new_function.__defaults__ = function.__defaults__129    return new_function130 131 132call = patched_function(subprocess_orig.call)133check_call = patched_function(subprocess_orig.check_call)134# check_output is Python 2.7+135if hasattr(subprocess_orig, 'check_output'):136    __patched__.append('check_output')137    check_output = patched_function(subprocess_orig.check_output)138del patched_function139 140# Keep exceptions identity.141# https://github.com/eventlet/eventlet/issues/413142CalledProcessError = subprocess_imported.CalledProcessError143del subprocess_imported144 
codekingpro/portable-devtools · Team Ai