spacepaste

  1.  
  2. def rmdirRecursiveSub(dir, do_ignore_remove_fails):
  3. """This is a replacement for shutil.rmtree that works better under
  4. windows. Thanks to Bear at the OSAF for the code."""
  5. if not os.path.exists(dir):
  6. return
  7. try:
  8. if os.path.islink(dir) or os.path.isfile(dir):
  9. os.remove(dir)
  10. return
  11. # Verify the directory is read/write/execute for the current user
  12. os.chmod(dir, 0700)
  13. # os.listdir below only returns a list of unicode filenames if the parameter is unicode
  14. # Thus, if a non-unicode-named dir contains a unicode filename, that filename will get garbled.
  15. # So force dir to be unicode.
  16. if not isinstance(dir, unicode):
  17. try:
  18. dir = unicode(dir, "utf-8")
  19. except:
  20. log.err("rmdirRecursive: decoding from UTF-8 failed (ignoring)")
  21. try:
  22. list = os.listdir(dir)
  23. except WindowsError, e:
  24. msg = ("rmdirRecursive: unable to listdir %s (%s). Trying to "
  25. "remove like a dir" % (dir, e.strerror.decode('mbcs')))
  26. log.msg(msg.encode('utf-8'))
  27. os.rmdir(dir)
  28. return
  29. for name in list:
  30. full_name = os.path.join(dir, name)
  31. # on Windows, if we don't have write permission we can't remove
  32. # the file/directory either, so turn that on
  33. if os.name == 'nt':
  34. if not os.access(full_name, os.W_OK):
  35. # I think this is now redundant, but I don't have an NT
  36. # machine to test on, so I'm going to leave it in place
  37. # -warner
  38. os.chmod(full_name, 0600)
  39. if os.path.islink(full_name):
  40. os.remove(full_name) # as suggested in bug #792
  41. elif os.path.isdir(full_name):
  42. rmdirRecursiveSub(full_name, True)
  43. else:
  44. if os.path.isfile(full_name):
  45. os.chmod(full_name, 0700)
  46. os.remove(full_name)
  47. os.rmdir(dir)
  48. except OSError as e:
  49. if e.errno in (errno.ENOTEMPTY, errno.EBUSY, errno.EACCES):
  50. if not do_ignore_remove_fails:
  51. msg = None
  52. try:
  53. list2 = os.listdir(dir)
  54. msg = 'rmdirRecursive: directory not empty: {0}. Contains: {1}. New: {2}.'
  55. msg = msg.format(repr(dir), repr(list2), repr(sorted(set(list2) - set(list))))
  56. except:
  57. pass
  58. if msg is None:
  59. raise
  60. raise OSError(e.errno, msg)
  61. elif e.errno == errno.ENOENT:
  62. pass
  63. else:
  64. raise
  65. def rmdirRecursive(dir):
  66. tries_left = 5 # number of tries
  67. delay_between_tries = 5 # dely in seconds between tries
  68. while True:
  69. try:
  70. rmdirRecursiveSub(dir, False)
  71. break
  72. except OSError as e:
  73. tries_left -= 1
  74. if not e.errno in (errno.ENOTEMPTY, errno.EBUSY, errno.EACCES):
  75. raise
  76. if tries_left <= 0:
  77. raise
  78. # try again after some waiting
  79. time.sleep(delay_between_tries)
  80.