def monkey_patch(**modules):
    """Globally patch/configure system modules to to be greenlet-friendly

    If no keyword arguments are specified, all possible modules are patched. If keyword arguments
    are specified, the specified modules (and their dependencies) will be patched.

    - Patching :mod:`socket` will also patch :mod:`ssl`
    - Patching :mod:`threading` will also patch :mod:`_thread` and :mod:`queue`

    It's safe to call monkey_patch multiple times.

    Example::

        monkey_patch(time=True, socket=True, select=True)

    :keyword bool time: time module: patches sleep()
    :keyword bool os: os module: patches open(), read(), write(), wait(), waitpid()
    :keyword bool socket: socket module: patches socket, create_connection()
    :keyword bool select: select module: patches select()
    :keyword bool threading: threading module: patches local, Lock(), stack_size(), current_thread()
    :keyword bool psycopg2: psycopg2 module: register a wait callback to yield
    :keyword bool cassandra: cassandra module: set connection class to GuvConnection
    """
    log.debug('Begin monkey-patching')
    accepted_args = {'os', 'select', 'socket', 'threading', 'time', 'psycopg2',
                     'cassandra', '__builtin__'}
    default_modules = modules.pop('all', None)
    for k in modules.keys():
        if k not in accepted_args:
            raise TypeError('monkey_patch() got an unexpected keyword argument %r' % k)
    if default_modules is None:
        default_modules = not (True in modules.values())
    for modname in accepted_args:
        if modname == '__builtin__':
            modules.setdefault(modname, False)
        modules.setdefault(modname, default_modules)

    modules_to_patch = []
    if modules['os'] and not already_patched.get('os'):
        modules_to_patch += _green_os_modules()
        already_patched['os'] = True
    if modules['select'] and not already_patched.get('select'):
        modules_to_patch += _green_select_modules()
        already_patched['select'] = True
    if modules['socket'] and not already_patched.get('socket'):
        modules_to_patch += _green_socket_modules()
        already_patched['socket'] = True
    if modules['threading'] and not already_patched.get('threading'):
        modules_to_patch += _green_thread_modules()
        already_patched['threading'] = True
    if modules['time'] and not already_patched.get('time'):
        modules_to_patch += _green_time_modules()
        already_patched['time'] = True
    if modules.get('__builtin__') and not already_patched.get('__builtin__'):
        modules_to_patch += _green_builtins()
        already_patched['__builtin__'] = True
    if modules['psycopg2'] and not already_patched.get('psycopg2'):
        try:
            from guv.support import psycopg2_patcher

            psycopg2_patcher.make_psycopg_green()
            already_patched['psycopg2'] = True
        except ImportError:
            pass

    imp.acquire_lock()
    try:
        for name, mod in modules_to_patch:
            log.debug('patch: {:20} -> {}'.format(name, mod))
            orig_mod = sys.modules.get(name)
            if orig_mod is None:
                orig_mod = importlib.import_module(name)
            for attr_name in mod.__patched__:
                patched_attr = getattr(mod, attr_name, None)
                if patched_attr is not None:
                    setattr(orig_mod, attr_name, patched_attr)
    finally:
        imp.release_lock()

    # Cassandra must be patched after other modules have been patched
    if modules['cassandra'] and not already_patched.get('cassandra'):
        try:
            import cassandra.cluster
            from guv.support.cassandra import GuvConnection

            cassandra.cluster.DefaultConnection = GuvConnection
            cassandra.cluster.Cluster.connection_class = GuvConnection

            already_patched['cassandra'] = True
        except ImportError:
            pass
dataset/ETHPy150Open veegee/guv/guv/patcher.py/monkey_patch/original