diff options
author | Eric V. Smith <eric@trueblade.com> | 2012-06-28 10:15:30 (GMT) |
---|---|---|
committer | Eric V. Smith <eric@trueblade.com> | 2012-06-28 10:15:30 (GMT) |
commit | abb755db11b8f5a5a0b9c97540e3fb4e161e1894 (patch) | |
tree | 94f17fef98e5d22224856d97cb0ab54b403a6a92 /Lib | |
parent | b10951549b5f49849d44cdbac02c35146d5d05d3 (diff) | |
parent | a75cd1ce73f627f12329b782922dfc85387be3cc (diff) | |
download | cpython-abb755db11b8f5a5a0b9c97540e3fb4e161e1894.zip cpython-abb755db11b8f5a5a0b9c97540e3fb4e161e1894.tar.gz cpython-abb755db11b8f5a5a0b9c97540e3fb4e161e1894.tar.bz2 |
Merge.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/shutil.py | 4 | ||||
-rw-r--r-- | Lib/test/test_shutil.py | 34 |
2 files changed, 35 insertions, 3 deletions
diff --git a/Lib/shutil.py b/Lib/shutil.py index 3cafd01..da5a98e 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -380,7 +380,7 @@ def _rmtree_safe_fd(topfd, path, onerror): for name in names: fullname = os.path.join(path, name) try: - orig_st = os.stat(name, dir_fd=topfd) + orig_st = os.stat(name, dir_fd=topfd, follow_symlinks=False) mode = orig_st.st_mode except os.error: mode = 0 @@ -445,7 +445,7 @@ def rmtree(path, ignore_errors=False, onerror=None): if (stat.S_ISDIR(orig_st.st_mode) and os.path.samestat(orig_st, os.fstat(fd))): _rmtree_safe_fd(fd, path, onerror) - elif (stat.S_ISREG(orig_st.st_mode)): + else: raise NotADirectoryError(20, "Not a directory: '{}'".format(path)) finally: diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 49be391..cb712b3 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -117,6 +117,38 @@ class TestShutil(unittest.TestCase): self.assertIsInstance(victim, bytes) shutil.rmtree(victim) + @support.skip_unless_symlink + def test_rmtree_fails_on_symlink(self): + tmp = self.mkdtemp() + dir_ = os.path.join(tmp, 'dir') + os.mkdir(dir_) + link = os.path.join(tmp, 'link') + os.symlink(dir_, link) + self.assertRaises(OSError, shutil.rmtree, link) + self.assertTrue(os.path.exists(dir_)) + + @support.skip_unless_symlink + def test_rmtree_works_on_symlinks(self): + tmp = self.mkdtemp() + dir1 = os.path.join(tmp, 'dir1') + dir2 = os.path.join(dir1, 'dir2') + dir3 = os.path.join(tmp, 'dir3') + for d in dir1, dir2, dir3: + os.mkdir(d) + file1 = os.path.join(tmp, 'file1') + write_file(file1, 'foo') + link1 = os.path.join(dir1, 'link1') + os.symlink(dir2, link1) + link2 = os.path.join(dir1, 'link2') + os.symlink(dir3, link2) + link3 = os.path.join(dir1, 'link3') + os.symlink(file1, link3) + # make sure symlinks are removed but not followed + shutil.rmtree(dir1) + self.assertFalse(os.path.exists(dir1)) + self.assertTrue(os.path.exists(dir3)) + self.assertTrue(os.path.exists(file1)) + def test_rmtree_errors(self): # filename is guaranteed not to exist filename = tempfile.mktemp() @@ -184,7 +216,7 @@ class TestShutil(unittest.TestCase): def test_rmtree_does_not_choke_on_failing_lstat(self): try: orig_lstat = os.lstat - def raiser(fn): + def raiser(fn, *args, **kwargs): if fn != TESTFN: raise OSError() else: |