-
- def rmdirRecursiveSub(dir, do_ignore_remove_fails):
- """This is a replacement for shutil.rmtree that works better under
- windows. Thanks to Bear at the OSAF for the code."""
- if not os.path.exists(dir):
- return
-
- try:
-
- if os.path.islink(dir) or os.path.isfile(dir):
- os.remove(dir)
- return
-
- # Verify the directory is read/write/execute for the current user
- os.chmod(dir, 0700)
-
- # os.listdir below only returns a list of unicode filenames if the parameter is unicode
- # Thus, if a non-unicode-named dir contains a unicode filename, that filename will get garbled.
- # So force dir to be unicode.
- if not isinstance(dir, unicode):
- try:
- dir = unicode(dir, "utf-8")
- except:
- log.err("rmdirRecursive: decoding from UTF-8 failed (ignoring)")
-
- try:
- list = os.listdir(dir)
- except WindowsError, e:
- msg = ("rmdirRecursive: unable to listdir %s (%s). Trying to "
- "remove like a dir" % (dir, e.strerror.decode('mbcs')))
- log.msg(msg.encode('utf-8'))
- os.rmdir(dir)
- return
-
- for name in list:
- full_name = os.path.join(dir, name)
- # on Windows, if we don't have write permission we can't remove
- # the file/directory either, so turn that on
- if os.name == 'nt':
- if not os.access(full_name, os.W_OK):
- # I think this is now redundant, but I don't have an NT
- # machine to test on, so I'm going to leave it in place
- # -warner
- os.chmod(full_name, 0600)
-
- if os.path.islink(full_name):
- os.remove(full_name) # as suggested in bug #792
- elif os.path.isdir(full_name):
- rmdirRecursiveSub(full_name, True)
- else:
- if os.path.isfile(full_name):
- os.chmod(full_name, 0700)
- os.remove(full_name)
-
- os.rmdir(dir)
-
- except OSError as e:
- if e.errno in (errno.ENOTEMPTY, errno.EBUSY, errno.EACCES):
- if not do_ignore_remove_fails:
- msg = None
- try:
- list2 = os.listdir(dir)
- msg = 'rmdirRecursive: directory not empty: {0}. Contains: {1}. New: {2}.'
- msg = msg.format(repr(dir), repr(list2), repr(sorted(set(list2) - set(list))))
- except:
- pass
- if msg is None:
- raise
- raise OSError(e.errno, msg)
- elif e.errno == errno.ENOENT:
- pass
- else:
- raise
-
-
- def rmdirRecursive(dir):
- tries_left = 5 # number of tries
- delay_between_tries = 5 # dely in seconds between tries
-
- while True:
- try:
- rmdirRecursiveSub(dir, False)
- break
- except OSError as e:
- tries_left -= 1
- if not e.errno in (errno.ENOTEMPTY, errno.EBUSY, errno.EACCES):
- raise
- if tries_left <= 0:
- raise
- # try again after some waiting
- time.sleep(delay_between_tries)
-