diff options
Diffstat (limited to 'Lib/test/test_pathlib')
-rw-r--r-- | Lib/test/test_pathlib/test_pathlib.py | 13 | ||||
-rw-r--r-- | Lib/test/test_pathlib/test_pathlib_abc.py | 157 |
2 files changed, 170 insertions, 0 deletions
diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py index 89af1f7..6b5e90f 100644 --- a/Lib/test/test_pathlib/test_pathlib.py +++ b/Lib/test/test_pathlib/test_pathlib.py @@ -653,6 +653,19 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest): self.assertIsInstance(f, io.RawIOBase) self.assertEqual(f.read().strip(), b"this is file A") + @unittest.skipIf(sys.platform == "win32" or sys.platform == "wasi", "directories are always readable on Windows and WASI") + def test_copytree_no_read_permission(self): + base = self.cls(self.base) + source = base / 'dirE' + target = base / 'copyE' + self.assertRaises(PermissionError, source.copytree, target) + self.assertFalse(target.exists()) + errors = [] + source.copytree(target, on_error=errors.append) + self.assertEqual(len(errors), 1) + self.assertIsInstance(errors[0], PermissionError) + self.assertFalse(target.exists()) + def test_resolve_nonexist_relative_issue38671(self): p = self.cls('non', 'exist') diff --git a/Lib/test/test_pathlib/test_pathlib_abc.py b/Lib/test/test_pathlib/test_pathlib_abc.py index cd629c0..ad692e8 100644 --- a/Lib/test/test_pathlib/test_pathlib_abc.py +++ b/Lib/test/test_pathlib/test_pathlib_abc.py @@ -1822,6 +1822,163 @@ class DummyPathTest(DummyPurePathTest): self.assertTrue(target.exists()) self.assertEqual(target.read_bytes(), b'') + def test_copytree_simple(self): + base = self.cls(self.base) + source = base / 'dirC' + target = base / 'copyC' + source.copytree(target) + self.assertTrue(target.is_dir()) + self.assertTrue(target.joinpath('dirD').is_dir()) + self.assertTrue(target.joinpath('dirD', 'fileD').is_file()) + self.assertEqual(target.joinpath('dirD', 'fileD').read_text(), + "this is file D\n") + self.assertTrue(target.joinpath('fileC').is_file()) + self.assertTrue(target.joinpath('fileC').read_text(), + "this is file C\n") + + def test_copytree_complex(self, follow_symlinks=True): + def ordered_walk(path): + for dirpath, dirnames, filenames in path.walk(follow_symlinks=follow_symlinks): + dirnames.sort() + filenames.sort() + yield dirpath, dirnames, filenames + base = self.cls(self.base) + source = base / 'dirC' + + if self.can_symlink: + # Add some symlinks + source.joinpath('linkC').symlink_to('fileC') + source.joinpath('linkD').symlink_to('dirD') + + # Perform the copy + target = base / 'copyC' + source.copytree(target, follow_symlinks=follow_symlinks) + + # Compare the source and target trees + source_walk = ordered_walk(source) + target_walk = ordered_walk(target) + for source_item, target_item in zip(source_walk, target_walk, strict=True): + self.assertEqual(source_item[0].relative_to(source), + target_item[0].relative_to(target)) # dirpath + self.assertEqual(source_item[1], target_item[1]) # dirnames + self.assertEqual(source_item[2], target_item[2]) # filenames + # Compare files and symlinks + for filename in source_item[2]: + source_file = source_item[0].joinpath(filename) + target_file = target_item[0].joinpath(filename) + if follow_symlinks or not source_file.is_symlink(): + # Regular file. + self.assertEqual(source_file.read_bytes(), target_file.read_bytes()) + elif source_file.is_dir(): + # Symlink to directory. + self.assertTrue(target_file.is_dir()) + self.assertEqual(source_file.readlink(), target_file.readlink()) + else: + # Symlink to file. + self.assertEqual(source_file.read_bytes(), target_file.read_bytes()) + self.assertEqual(source_file.readlink(), target_file.readlink()) + + def test_copytree_complex_follow_symlinks_false(self): + self.test_copytree_complex(follow_symlinks=False) + + def test_copytree_to_existing_directory(self): + base = self.cls(self.base) + source = base / 'dirC' + target = base / 'copyC' + target.mkdir() + target.joinpath('dirD').mkdir() + self.assertRaises(FileExistsError, source.copytree, target) + + def test_copytree_to_existing_directory_dirs_exist_ok(self): + base = self.cls(self.base) + source = base / 'dirC' + target = base / 'copyC' + target.mkdir() + target.joinpath('dirD').mkdir() + source.copytree(target, dirs_exist_ok=True) + self.assertTrue(target.is_dir()) + self.assertTrue(target.joinpath('dirD').is_dir()) + self.assertTrue(target.joinpath('dirD', 'fileD').is_file()) + self.assertEqual(target.joinpath('dirD', 'fileD').read_text(), + "this is file D\n") + self.assertTrue(target.joinpath('fileC').is_file()) + self.assertTrue(target.joinpath('fileC').read_text(), + "this is file C\n") + + def test_copytree_file(self): + base = self.cls(self.base) + source = base / 'fileA' + target = base / 'copyA' + self.assertRaises(NotADirectoryError, source.copytree, target) + + def test_copytree_file_on_error(self): + base = self.cls(self.base) + source = base / 'fileA' + target = base / 'copyA' + errors = [] + source.copytree(target, on_error=errors.append) + self.assertEqual(len(errors), 1) + self.assertIsInstance(errors[0], NotADirectoryError) + + def test_copytree_ignore_false(self): + base = self.cls(self.base) + source = base / 'dirC' + target = base / 'copyC' + ignores = [] + def ignore_false(path): + ignores.append(path) + return False + source.copytree(target, ignore=ignore_false) + self.assertEqual(set(ignores), { + source / 'dirD', + source / 'dirD' / 'fileD', + source / 'fileC', + source / 'novel.txt', + }) + self.assertTrue(target.is_dir()) + self.assertTrue(target.joinpath('dirD').is_dir()) + self.assertTrue(target.joinpath('dirD', 'fileD').is_file()) + self.assertEqual(target.joinpath('dirD', 'fileD').read_text(), + "this is file D\n") + self.assertTrue(target.joinpath('fileC').is_file()) + self.assertTrue(target.joinpath('fileC').read_text(), + "this is file C\n") + + def test_copytree_ignore_true(self): + base = self.cls(self.base) + source = base / 'dirC' + target = base / 'copyC' + ignores = [] + def ignore_true(path): + ignores.append(path) + return True + source.copytree(target, ignore=ignore_true) + self.assertEqual(set(ignores), { + source / 'dirD', + source / 'fileC', + source / 'novel.txt', + }) + self.assertTrue(target.is_dir()) + self.assertFalse(target.joinpath('dirD').exists()) + self.assertFalse(target.joinpath('fileC').exists()) + self.assertFalse(target.joinpath('novel.txt').exists()) + + @needs_symlinks + def test_copytree_dangling_symlink(self): + base = self.cls(self.base) + source = base / 'source' + target = base / 'target' + + source.mkdir() + source.joinpath('link').symlink_to('nonexistent') + + self.assertRaises(FileNotFoundError, source.copytree, target) + + target2 = base / 'target2' + source.copytree(target2, follow_symlinks=False) + self.assertTrue(target2.joinpath('link').is_symlink()) + self.assertEqual(target2.joinpath('link').readlink(), self.cls('nonexistent')) + def test_iterdir(self): P = self.cls p = P(self.base) |