import types


def copy_func(f, name=None):
    """
    Return a function with same code, globals, closure, and name (or provided name).
    """
    fn = types.FunctionType(f.__code__, f.__globals__, name or f.__name__,
            f.__defaults__, f.__closure__)
    # If f has been given attributes
    fn.__dict__.update(f.__dict__)
    return fn