Bug 859422 - Document why mozfile.remove works better than shutil.rmtree. r=wlach
authorJulien Pagès <j.parkouss@gmail.com>
Sat, 11 Oct 2014 10:33:00 -0400
changeset 210007 c0d968dc9a29611ea01d51bbbb7fb28f01c72e80
parent 210006 5ec529e71a22b16e6de6c553ca7cdf13b876bcf6
child 210026 199fb29c3467cbf06cd4e7d6ef5ea2323530d211
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerswlach
bugs859422
milestone35.0a1
Bug 859422 - Document why mozfile.remove works better than shutil.rmtree. r=wlach
testing/mozbase/mozfile/mozfile/mozfile.py
testing/mozbase/mozfile/tests/test_remove.py
--- 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()