diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-05-31 08:30:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-31 08:30:37 (GMT) |
commit | e9b51c0ad81da1da11ae65840ac8b50a8521373c (patch) | |
tree | 612f275e9aa504fdf3e5e18d736f19bf56fdb06f /Lib/test/test_tempfile.py | |
parent | 38ab7d4721b422547f7b46b9d68968863fa70573 (diff) | |
download | cpython-e9b51c0ad81da1da11ae65840ac8b50a8521373c.zip cpython-e9b51c0ad81da1da11ae65840ac8b50a8521373c.tar.gz cpython-e9b51c0ad81da1da11ae65840ac8b50a8521373c.tar.bz2 |
bpo-26660, bpo-35144: Fix permission errors in TemporaryDirectory cleanup. (GH-10320)
TemporaryDirectory.cleanup() failed when non-writeable or non-searchable
files or directories were created inside a temporary directory.
Diffstat (limited to 'Lib/test/test_tempfile.py')
-rw-r--r-- | Lib/test/test_tempfile.py | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 489141d..bd4db83 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1297,19 +1297,25 @@ class NulledModules: class TestTemporaryDirectory(BaseTestCase): """Test TemporaryDirectory().""" - def do_create(self, dir=None, pre="", suf="", recurse=1): + def do_create(self, dir=None, pre="", suf="", recurse=1, dirs=1, files=1): if dir is None: dir = tempfile.gettempdir() tmp = tempfile.TemporaryDirectory(dir=dir, prefix=pre, suffix=suf) self.nameCheck(tmp.name, dir, pre, suf) - # Create a subdirectory and some files - if recurse: - d1 = self.do_create(tmp.name, pre, suf, recurse-1) - d1.name = None - with open(os.path.join(tmp.name, "test.txt"), "wb") as f: - f.write(b"Hello world!") + self.do_create2(tmp.name, recurse, dirs, files) return tmp + def do_create2(self, path, recurse=1, dirs=1, files=1): + # Create subdirectories and some files + if recurse: + for i in range(dirs): + name = os.path.join(path, "dir%d" % i) + os.mkdir(name) + self.do_create2(name, recurse-1, dirs, files) + for i in range(files): + with open(os.path.join(path, "test%d.txt" % i), "wb") as f: + f.write(b"Hello world!") + def test_mkdtemp_failure(self): # Check no additional exception if mkdtemp fails # Previously would raise AttributeError instead @@ -1349,7 +1355,7 @@ class TestTemporaryDirectory(BaseTestCase): "TemporaryDirectory %s exists after cleanup" % d1.name) self.assertTrue(os.path.exists(d2.name), "Directory pointed to by a symlink was deleted") - self.assertEqual(os.listdir(d2.name), ['test.txt'], + self.assertEqual(os.listdir(d2.name), ['test0.txt'], "Contents of the directory pointed to by a symlink " "were deleted") d2.cleanup() @@ -1384,7 +1390,7 @@ class TestTemporaryDirectory(BaseTestCase): tmp2 = os.path.join(tmp.name, 'test_dir') os.mkdir(tmp2) - with open(os.path.join(tmp2, "test.txt"), "w") as f: + with open(os.path.join(tmp2, "test0.txt"), "w") as f: f.write("Hello world!") {mod}.tmp = tmp @@ -1452,6 +1458,33 @@ class TestTemporaryDirectory(BaseTestCase): self.assertEqual(name, d.name) self.assertFalse(os.path.exists(name)) + def test_modes(self): + for mode in range(8): + mode <<= 6 + with self.subTest(mode=format(mode, '03o')): + d = self.do_create(recurse=3, dirs=2, files=2) + with d: + # Change files and directories mode recursively. + for root, dirs, files in os.walk(d.name, topdown=False): + for name in files: + os.chmod(os.path.join(root, name), mode) + os.chmod(root, mode) + d.cleanup() + self.assertFalse(os.path.exists(d.name)) + + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + def test_flags(self): + flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + d = self.do_create(recurse=3, dirs=2, files=2) + with d: + # Change files and directories flags recursively. + for root, dirs, files in os.walk(d.name, topdown=False): + for name in files: + os.chflags(os.path.join(root, name), flags) + os.chflags(root, flags) + d.cleanup() + self.assertFalse(os.path.exists(d.name)) + if __name__ == "__main__": unittest.main() |