Bug 859422 - Document why mozfile.remove works better than shutil.rmtree. r=wlach
--- a/testing/mozbase/mozfile/mozfile/mozfile.py
+++ b/testing/mozbase/mozfile/mozfile/mozfile.py
@@ -128,20 +128,29 @@ def rmtree(dir):
"""
warnings.warn("mozfile.rmtree() is deprecated in favor of mozfile.remove()",
PendingDeprecationWarning, stacklevel=2)
return remove(dir)
def remove(path):
- """Removes the specified file, link, or directory tree
+ """Removes the specified file, link, or directory tree.
This is a replacement for shutil.rmtree that works better under
- windows.
+ windows. It does the following things:
+
+ - check path access for the current user before trying to remove
+ - retry operations on some known errors due to various things keeping
+ a handle on file paths - like explorer, virus scanners, etc. The
+ known errors are errno.EACCES and errno.ENOTEMPTY, and it will
+ retry up to 5 five times with a delay of 0.5 seconds between each
+ attempt.
+
+ Note that no error will be raised if the given path does not exists.
:param path: path to be removed
"""
import shutil
def _call_with_windows_retry(func, args=(), retry_max=5, retry_delay=0.5):
"""
--- a/testing/mozbase/mozfile/tests/test_remove.py
+++ b/testing/mozbase/mozfile/tests/test_remove.py
@@ -1,16 +1,17 @@
#!/usr/bin/env python
import os
import stat
import shutil
import threading
import time
import unittest
+import errno
import mozfile
import mozinfo
import stubs
def mark_readonly(path):
@@ -176,8 +177,20 @@ class MozfileRemoveTestCase(unittest.Tes
os.symlink(os.path.dirname(self.tempdir), symlink_path)
self.assertTrue(os.path.islink(symlink_path))
# The folder with the contained symlink will be deleted but not the
# original linked file
mozfile.remove(symlink_path)
self.assertFalse(os.path.exists(symlink_path))
+
+ def test_remove_path_that_does_not_exists(self):
+ not_existing_path = os.path.join(self.tempdir, 'I_do_not_not_exists')
+ try:
+ mozfile.remove(not_existing_path)
+ except OSError, exc:
+ if exc.errno == errno.ENOENT:
+ self.fail("removing non existing path must not raise error")
+ raise
+
+if __name__ == '__main__':
+ unittest.main()