diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-11-20 14:19:20 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-11-20 14:19:20 (GMT) |
commit | 0e7dbe901ca5e5587d18bdfaceeba244ab5342ca (patch) | |
tree | 65913e436685186ae60ca8ace51abf4ebfcf1d17 /Lib/test/support/__init__.py | |
parent | 92b9a1f9114fc83ba4d3dcc760012097c60a11df (diff) | |
parent | 6770f8a4877eba56dd9978caf197795dbc3d3ffb (diff) | |
download | cpython-0e7dbe901ca5e5587d18bdfaceeba244ab5342ca.zip cpython-0e7dbe901ca5e5587d18bdfaceeba244ab5342ca.tar.gz cpython-0e7dbe901ca5e5587d18bdfaceeba244ab5342ca.tar.bz2 |
Issue #28666: Now test.support.rmtree is able to remove unwritable or
unreadable directories.
Diffstat (limited to 'Lib/test/support/__init__.py')
-rw-r--r-- | Lib/test/support/__init__.py | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index f106723..503ae2d 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -358,7 +358,37 @@ if sys.platform.startswith("win"): 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: |