mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Issue #28666: Now test.support.rmtree is able to remove unwritable or
unreadable directories.
This commit is contained in:
		
						commit
						0e7dbe901c
					
				
					 3 changed files with 56 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -358,7 +358,37 @@ def _rmtree_inner(path):
 | 
			
		|||
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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 @@ def test_unlink(self):
 | 
			
		|||
        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'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,6 +82,9 @@ Documentation
 | 
			
		|||
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.
 | 
			
		||||
 | 
			
		||||
Build
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue