From: Serhiy Storchaka Date: Sun, 20 Nov 2016 14:15:35 +0000 (+0200) Subject: Issue #28666: Now test.support.rmtree is able to remove unwritable or X-Git-Tag: v2.7.13rc1~32 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7c057a143d94cd77443d35c70bc6e47b211617c;p=python Issue #28666: Now test.support.rmtree is able to remove unwritable or unreadable directories. --- diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 2fba2a36d7..ce38ab7925 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -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: diff --git a/Misc/NEWS b/Misc/NEWS index f4c97b689f..f8424682e2 100644 --- 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