def handle_remove_readonly(func, path, exc):
    'Error handler for shutil.rmtree.\n\n    Windows source repo folders are read-only by default, so this error handler\n    attempts to set them as writeable and then proceed with deletion.'
    default_warning_message = 'Unable to remove file due to permissions restriction: {!r}'
    (exc_type, exc_exception, exc_tb) = exc
    if is_readonly_path(path):
        set_write_bit(path)
        try:
            func(path)
        except (OSError, IOError) as e:
            if (e.errno in [errno.EACCES, errno.EPERM]):
                warnings.warn(default_warning_message.format(path), ResourceWarning)
                return
    if (exc_exception.errno in [errno.EACCES, errno.EPERM]):
        warnings.warn(default_warning_message.format(path), ResourceWarning)
        return
    raise
Error handler for shutil.rmtree.

Windows source repo folders are read-only by default, so this error handler
attempts to set them as writeable and then proceed with deletion.
def handle_remove_readonly(func, path, exc):
    'Error handler for shutil.rmtree.\n\n    Windows source repo folders are read-only by default, so this error handler\n    attempts to set them as writeable and then proceed with deletion.'
    default_warning_message = 'Unable to remove file due to permissions restriction: {!r}'
    (exc_type, exc_exception, exc_tb) = exc
    if is_readonly_path(path):
        set_write_bit(path)
        try:
            func(path)
        except (OSError, IOError) as e:
            if (e.errno in [errno.EACCES, errno.EPERM]):
                warnings.warn(default_warning_message.format(path), ResourceWarning)
                return
    if (exc_exception.errno in [errno.EACCES, errno.EPERM]):
        warnings.warn(default_warning_message.format(path), ResourceWarning)
        return
    raise