def rmtree(path, ignore_errors=False, onerror=None): """Recursively delete a directory tree. If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, err) where func is os.listdir, os.remove, or os.rmdir; path is the argument to that function that caused it to fail; and err is an os.error exception instance. If ignore_errors is false and onerror is None, an exception is raised. """ def call_and_handle_error(func, path): try: return func(path) except os.error: exc = sys.exc_info() if onerror is not None: onerror(func, path, exc) elif not ignore_errors: raise names = [] names = call_and_handle_error(os.listdir, path) for name in names: fullname = os.path.join(path, name) if os.path.isdir(fullname) and not os.path.islink(fullname): rmtree(fullname, ignore_errors, onerror) else: call_and_handle_error(os.remove, fullname) call_and_handle_error(os.rmdir, path)