summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_pathlib
diff options
context:
space:
mode:
authorBarney Gale <barney.gale@gmail.com>2024-07-20 22:32:52 (GMT)
committerGitHub <noreply@github.com>2024-07-20 22:32:52 (GMT)
commitc4c7097e64b0c9cb0081de8872b90594865c892b (patch)
tree0a0ef494b3df9b78c90f49031318cc0b4f9148a8 /Lib/test/test_pathlib
parent094375b9b7e087a4f0f60541dc7f2dc53be92646 (diff)
downloadcpython-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.py30
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')