summaryrefslogtreecommitdiffstats
path: root/Lib/pathlib/_abc.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/pathlib/_abc.py')
-rw-r--r--Lib/pathlib/_abc.py31
1 files changed, 30 insertions, 1 deletions
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index b5f903e..05f55ba 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -781,7 +781,32 @@ class PathBase(PurePathBase):
"""
raise UnsupportedOperation(self._unsupported_msg('mkdir()'))
- def copy(self, target, follow_symlinks=True):
+ # Metadata keys supported by this path type.
+ _readable_metadata = _writable_metadata = frozenset()
+
+ def _read_metadata(self, keys=None, *, follow_symlinks=True):
+ """
+ Returns path metadata as a dict with string keys.
+ """
+ raise UnsupportedOperation(self._unsupported_msg('_read_metadata()'))
+
+ def _write_metadata(self, metadata, *, follow_symlinks=True):
+ """
+ Sets path metadata from the given dict with string keys.
+ """
+ raise UnsupportedOperation(self._unsupported_msg('_write_metadata()'))
+
+ def _copy_metadata(self, target, *, follow_symlinks=True):
+ """
+ Copies metadata (permissions, timestamps, etc) from this path to target.
+ """
+ # Metadata types supported by both source and target.
+ keys = self._readable_metadata & target._writable_metadata
+ if keys:
+ metadata = self._read_metadata(keys, follow_symlinks=follow_symlinks)
+ target._write_metadata(metadata, follow_symlinks=follow_symlinks)
+
+ def copy(self, target, *, follow_symlinks=True, preserve_metadata=False):
"""
Copy the contents of this file to the given target. If this file is a
symlink and follow_symlinks is false, a symlink will be created at the
@@ -793,6 +818,8 @@ class PathBase(PurePathBase):
raise OSError(f"{self!r} and {target!r} are the same file")
if not follow_symlinks and self.is_symlink():
target.symlink_to(self.readlink())
+ if preserve_metadata:
+ self._copy_metadata(target, follow_symlinks=False)
return
with self.open('rb') as source_f:
try:
@@ -805,6 +832,8 @@ class PathBase(PurePathBase):
f'Directory does not exist: {target}') from e
else:
raise
+ if preserve_metadata:
+ self._copy_metadata(target)
def copytree(self, target, *, follow_symlinks=True, dirs_exist_ok=False,
ignore=None, on_error=None):