]> granicus.if.org Git - python/commitdiff
Issue #28666: Now test.support.rmtree is able to remove unwritable or
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 20 Nov 2016 14:15:35 +0000 (16:15 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 20 Nov 2016 14:15:35 +0000 (16:15 +0200)
unreadable directories.

Lib/test/test_support.py
Misc/NEWS

index 2fba2a36d7b0c4093f5cabc19f0bcee33b09742e..ce38ab792558f55f3753efcb074850a3fd1f89ff 100644 (file)
@@ -236,7 +236,38 @@ if sys.platform.startswith("win"):
 else:
     _unlink = os.unlink
     _rmdir = os.rmdir
-    _rmtree = shutil.rmtree
+
+    def _rmtree(path):
+        import stat
+        try:
+            shutil.rmtree(path)
+            return
+        except EnvironmentError:
+            pass
+
+        def force_run(path, func, *args):
+            try:
+                return func(*args)
+            except EnvironmentError as err:
+                if verbose >= 2:
+                    print('%s: %s' % (err.__class__.__name__, err))
+                    print('re-run %s%r' % (func.__name__, args))
+                os.chmod(path, stat.S_IRWXU)
+                return func(*args)
+        def _rmtree_inner(path):
+            for name in force_run(path, os.listdir, path):
+                fullname = os.path.join(path, name)
+                try:
+                    mode = os.lstat(fullname).st_mode
+                except EnvironmentError:
+                    mode = 0
+                if stat.S_ISDIR(mode):
+                    _rmtree_inner(fullname)
+                    force_run(path, os.rmdir, fullname)
+                else:
+                    force_run(path, os.unlink, fullname)
+        _rmtree_inner(path)
+        os.rmdir(path)
 
 def unlink(filename):
     try:
index f4c97b689f7dfc0e68138ae88ff8a885042b0f64..f8424682e29b3e0e960db696fd857aa93c0ecae7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -262,6 +262,9 @@ Documentation
 Tests
 -----
 
+- Issue #28666: Now test.test_support.rmtree is able to remove unwritable or
+  unreadable directories.
+
 - Issue #23839: Various caches now are cleared before running every test file.
 
 - Issue #27369: In test_pyexpat, avoid testing an error message detail that