def rmtree(path, ignore_errors=False, onerror=None):
if ignore_errors:<EOL><INDENT>def onerror(*args):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>elif onerror is None:<EOL><INDENT>def onerror(*args):<EOL><INDENT>raise<EOL><DEDENT><DEDENT>try:<EOL><INDENT>if os.path.islink(path):<EOL><INDENT>raise OSError("<STR_LIT>")<EOL><DEDENT><DEDENT>except OSError:<EOL><INDENT>onerror(os.path.islink, path, sys.exc_info())<EOL>return<EOL><DEDENT>names = []<EOL>try:<EOL><INDENT>names = os.listdir(path)<EOL><DEDENT>except os.error:<EOL><INDENT>onerror(os.listdir, path, sys.exc_info())<EOL><DEDENT>for name in names:<EOL><INDENT>fullname = os.path.join(path, name)<EOL>try:<EOL><INDENT>mode = os.lstat(fullname).st_mode<EOL><DEDENT>except os.error:<EOL><INDENT>mode = <NUM_LIT:0><EOL><DEDENT>if stat.S_ISDIR(mode):<EOL><INDENT>rmtree(fullname, ignore_errors, onerror)<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>os.remove(fullname)<EOL><DEDENT>except os.error:<EOL><INDENT>onerror(os.remove, fullname, sys.exc_info())<EOL><DEDENT><DEDENT><DEDENT>try:<EOL><INDENT>os.rmdir(path)<EOL><DEDENT>except os.error:<EOL><INDENT>onerror(os.rmdir, path, sys.exc_info())<EOL><DEDENT>
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, exc_info) where func is os.listdir, os.remove, or os.rmdir;
    path is the argument to that function that caused it to fail; and
    exc_info is a tuple returned by sys.exc_info().  If ignore_errors
    is false and onerror is None, an exception is raised.