Commit 7b4fd297 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #28666: Now test.support.rmtree is able to remove unwritable or

unreadable directories.
parents 8cf736e7 736c3b76
...@@ -358,7 +358,37 @@ if sys.platform.startswith("win"): ...@@ -358,7 +358,37 @@ if sys.platform.startswith("win"):
else: else:
_unlink = os.unlink _unlink = os.unlink
_rmdir = os.rmdir _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): def unlink(filename):
try: try:
......
import importlib import importlib
import shutil import shutil
import stat
import sys import sys
import os import os
import unittest import unittest
...@@ -12,9 +13,6 @@ TESTFN = support.TESTFN ...@@ -12,9 +13,6 @@ TESTFN = support.TESTFN
class TestSupport(unittest.TestCase): class TestSupport(unittest.TestCase):
def setUp(self):
support.unlink(TESTFN)
tearDown = setUp
def test_import_module(self): def test_import_module(self):
support.import_module("ftplib") support.import_module("ftplib")
...@@ -46,15 +44,28 @@ class TestSupport(unittest.TestCase): ...@@ -46,15 +44,28 @@ class TestSupport(unittest.TestCase):
support.unlink(TESTFN) support.unlink(TESTFN)
def test_rmtree(self): def test_rmtree(self):
TESTDIRN = os.path.basename(tempfile.mkdtemp(dir='.')) dirpath = support.TESTFN + 'd'
self.addCleanup(support.rmtree, TESTDIRN) subdirpath = os.path.join(dirpath, 'subdir')
support.rmtree(TESTDIRN) os.mkdir(dirpath)
os.mkdir(subdirpath)
os.mkdir(TESTDIRN) support.rmtree(dirpath)
os.mkdir(os.path.join(TESTDIRN, TESTDIRN)) self.assertFalse(os.path.exists(dirpath))
support.rmtree(TESTDIRN) with support.swap_attr(support, 'verbose', 0):
self.assertFalse(os.path.exists(TESTDIRN)) support.rmtree(dirpath)
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): def test_forget(self):
mod_filename = TESTFN + '.py' mod_filename = TESTFN + '.py'
......
...@@ -82,6 +82,9 @@ Documentation ...@@ -82,6 +82,9 @@ Documentation
Tests 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 #23839: Various caches now are cleared before running every test file.
Build Build
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment