diff options
author | Barney Gale <barney.gale@gmail.com> | 2024-07-20 22:32:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-20 22:32:52 (GMT) |
commit | c4c7097e64b0c9cb0081de8872b90594865c892b (patch) | |
tree | 0a0ef494b3df9b78c90f49031318cc0b4f9148a8 /Lib/test/test_pathlib | |
parent | 094375b9b7e087a4f0f60541dc7f2dc53be92646 (diff) | |
download | cpython-c4c7097e64b0c9cb0081de8872b90594865c892b.zip cpython-c4c7097e64b0c9cb0081de8872b90594865c892b.tar.gz cpython-c4c7097e64b0c9cb0081de8872b90594865c892b.tar.bz2 |
GH-73991: Support preserving metadata in `pathlib.Path.copytree()` (#121438)
Add *preserve_metadata* keyword-only argument to `pathlib.Path.copytree()`,
defaulting to false. When set to true, we copy timestamps, permissions,
extended attributes and flags where available, like `shutil.copystat()`.
Diffstat (limited to 'Lib/test/test_pathlib')
-rw-r--r-- | Lib/test/test_pathlib/test_pathlib.py | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py index e17e7d7..5293b5c 100644 --- a/Lib/test/test_pathlib/test_pathlib.py +++ b/Lib/test/test_pathlib/test_pathlib.py @@ -721,6 +721,36 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest): self.assertIsInstance(errors[0], PermissionError) self.assertFalse(target.exists()) + def test_copytree_preserve_metadata(self): + base = self.cls(self.base) + source = base / 'dirC' + if hasattr(os, 'chmod'): + os.chmod(source / 'dirD', stat.S_IRWXU | stat.S_IRWXO) + if hasattr(os, 'chflags') and hasattr(stat, 'UF_NODUMP'): + os.chflags(source / 'fileC', stat.UF_NODUMP) + target = base / 'copyA' + source.copytree(target, preserve_metadata=True) + + for subpath in ['.', 'fileC', 'dirD', 'dirD/fileD']: + source_st = source.joinpath(subpath).stat() + target_st = target.joinpath(subpath).stat() + self.assertLessEqual(source_st.st_atime, target_st.st_atime) + self.assertLessEqual(source_st.st_mtime, target_st.st_mtime) + self.assertEqual(source_st.st_mode, target_st.st_mode) + if hasattr(source_st, 'st_flags'): + self.assertEqual(source_st.st_flags, target_st.st_flags) + + @os_helper.skip_unless_xattr + def test_copytree_preserve_metadata_xattrs(self): + base = self.cls(self.base) + source = base / 'dirC' + source_file = source.joinpath('dirD', 'fileD') + os.setxattr(source_file, b'user.foo', b'42') + target = base / 'copyA' + source.copytree(target, preserve_metadata=True) + target_file = target.joinpath('dirD', 'fileD') + self.assertEqual(os.getxattr(target_file, b'user.foo'), b'42') + def test_resolve_nonexist_relative_issue38671(self): p = self.cls('non', 'exist') |