import and return a named module with patches applied locally only

    this function returns a module after importing it in such as way that it
    will operate cooperatively, but not overriding the module globally.

    >>> green_httplib = patched("httplib")
    >>> # using green_httplib will only block greenlets
    >>> import httplib
    >>> # using httplib will block threads/processes
    >>> # both can exist simultaneously

    :param module_name:
        the module's name that is to be imported. this can be a dot-delimited
        name, in which case the module at the end of the path is the one that
        will be returned
    :type module_name: str

    :returns:
        the module indicated by module_name, imported so that it will not block
        globally, but also not touching existing global modules

def patched(module_name):
    """import and return a named module with patches applied locally only

    this function returns a module after importing it in such as way that it
    will operate cooperatively, but not overriding the module globally.

    >>> green_httplib = patched("httplib")
    >>> # using green_httplib will only block greenlets
    >>> import httplib
    >>> # using httplib will block threads/processes
    >>> # both can exist simultaneously

    :param module_name:
        the module's name that is to be imported. this can be a dot-delimited
        name, in which case the module at the end of the path is the one that
        will be returned
    :type module_name: str

    :returns:
        the module indicated by module_name, imported so that it will not block
        globally, but also not touching existing global modules
    """
    if module_name in _patchers:
        return _patched_copy(module_name, _patchers[module_name])

    # grab the unpatched version of the module for posterity
    old_module = sys.modules.pop(module_name, None)

    # apply all the standard library patches we have
    saved = [(module_name, old_module)]
    for name, patch in _patchers.iteritems():
        new_mod = _patched_copy(name, patch)
        saved.append((name, sys.modules.pop(name)))
        sys.modules[name] = new_mod

    try:
        # import the requested module with patches in place
        result = __import__(module_name, {}, {}, module_name.rsplit(".", 1)[0])
    finally:
        # put all the original modules back as they were
        for name, old_mod in saved:
            if old_mod is None:
                sys.modules.pop(name, None)
            else:
                sys.modules[name] = old_mod

    return result