Skip to content

Commit b7c057a

Browse files
Issue python#28666: Now test.support.rmtree is able to remove unwritable or
unreadable directories.
1 parent bd20530 commit b7c057a

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

Lib/test/test_support.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,38 @@ def _rmtree_inner(path):
236236
else:
237237
_unlink = os.unlink
238238
_rmdir = os.rmdir
239-
_rmtree = shutil.rmtree
239+
240+
def _rmtree(path):
241+
import stat
242+
try:
243+
shutil.rmtree(path)
244+
return
245+
except EnvironmentError:
246+
pass
247+
248+
def force_run(path, func, *args):
249+
try:
250+
return func(*args)
251+
except EnvironmentError as err:
252+
if verbose >= 2:
253+
print('%s: %s' % (err.__class__.__name__, err))
254+
print('re-run %s%r' % (func.__name__, args))
255+
os.chmod(path, stat.S_IRWXU)
256+
return func(*args)
257+
def _rmtree_inner(path):
258+
for name in force_run(path, os.listdir, path):
259+
fullname = os.path.join(path, name)
260+
try:
261+
mode = os.lstat(fullname).st_mode
262+
except EnvironmentError:
263+
mode = 0
264+
if stat.S_ISDIR(mode):
265+
_rmtree_inner(fullname)
266+
force_run(path, os.rmdir, fullname)
267+
else:
268+
force_run(path, os.unlink, fullname)
269+
_rmtree_inner(path)
270+
os.rmdir(path)
240271

241272
def unlink(filename):
242273
try:

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ Documentation
262262
Tests
263263
-----
264264

265+
- Issue #28666: Now test.test_support.rmtree is able to remove unwritable or
266+
unreadable directories.
267+
265268
- Issue #23839: Various caches now are cleared before running every test file.
266269

267270
- Issue #27369: In test_pyexpat, avoid testing an error message detail that

0 commit comments

Comments
 (0)