[Python-checkins] cpython (merge 3.6 -> default): Issue #28666: Now test.support.rmtree is able to remove unwritable or
serhiy.storchaka
python-checkins at python.org
Sun Nov 20 09:28:55 EST 2016
https://hg.python.org/cpython/rev/3a1e75ecc17d
changeset: 105218:3a1e75ecc17d
parent: 105214:f692dafe6797
parent: 105217:efe2993b20e2
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sun Nov 20 16:20:20 2016 +0200
summary:
Issue #28666: Now test.support.rmtree is able to remove unwritable or
unreadable directories.
files:
Lib/test/support/__init__.py | 32 ++++++++++++++++++++++-
Lib/test/test_support.py | 33 ++++++++++++++++--------
Misc/NEWS | 3 ++
3 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -358,7 +358,37 @@
else:
_unlink = os.unlink
_rmdir = os.rmdir
- _rmtree = shutil.rmtree
+
+ def _rmtree(path):
+ try:
+ shutil.rmtree(path)
+ return
+ except OSError:
+ pass
+
+ def force_run(path, func, *args):
+ try:
+ return func(*args)
+ except OSError 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 OSError:
+ 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:
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -1,5 +1,6 @@
import importlib
import shutil
+import stat
import sys
import os
import unittest
@@ -12,9 +13,6 @@
class TestSupport(unittest.TestCase):
- def setUp(self):
- support.unlink(TESTFN)
- tearDown = setUp
def test_import_module(self):
support.import_module("ftplib")
@@ -46,15 +44,28 @@
support.unlink(TESTFN)
def test_rmtree(self):
- TESTDIRN = os.path.basename(tempfile.mkdtemp(dir='.'))
- self.addCleanup(support.rmtree, TESTDIRN)
- support.rmtree(TESTDIRN)
+ dirpath = support.TESTFN + 'd'
+ subdirpath = os.path.join(dirpath, 'subdir')
+ os.mkdir(dirpath)
+ os.mkdir(subdirpath)
+ support.rmtree(dirpath)
+ self.assertFalse(os.path.exists(dirpath))
+ with support.swap_attr(support, 'verbose', 0):
+ support.rmtree(dirpath)
- os.mkdir(TESTDIRN)
- os.mkdir(os.path.join(TESTDIRN, TESTDIRN))
- support.rmtree(TESTDIRN)
- self.assertFalse(os.path.exists(TESTDIRN))
- support.rmtree(TESTDIRN)
+ os.mkdir(dirpath)
+ os.mkdir(subdirpath)
+ os.chmod(dirpath, stat.S_IRUSR|stat.S_IXUSR)
+ with support.swap_attr(support, 'verbose', 0):
+ support.rmtree(dirpath)
+ self.assertFalse(os.path.exists(dirpath))
+
+ os.mkdir(dirpath)
+ os.mkdir(subdirpath)
+ os.chmod(dirpath, 0)
+ with support.swap_attr(support, 'verbose', 0):
+ support.rmtree(dirpath)
+ self.assertFalse(os.path.exists(dirpath))
def test_forget(self):
mod_filename = TESTFN + '.py'
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -470,6 +470,9 @@
Tests
-----
+- Issue #28666: Now test.support.rmtree is able to remove unwritable or
+ unreadable directories.
+
- Issue #23839: Various caches now are cleared before running every test file.
- Issue #26944: Fix test_posix for Android where 'id -G' is entirely wrong or
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list