Skip to content

Commit

Permalink
Fix copying metadata to non-symlinks
Browse files Browse the repository at this point in the history
  • Loading branch information
barneygale committed Jul 28, 2024
1 parent a67f5a7 commit 017dd86
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
24 changes: 17 additions & 7 deletions Lib/pathlib/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,16 @@ def _write_metadata(self, metadata, *, follow_symlinks=True):
"""
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_data(self, target):
"""
Copy the contents of this file to the given target.
Expand Down Expand Up @@ -839,20 +849,20 @@ def on_error(err):
try:
if not follow_symlinks and source.is_symlink():
target.symlink_to(source.readlink())
elif source.is_dir():
if preserve_metadata:
source._copy_metadata(target, follow_symlinks=False)
elif source.is_dir(follow_symlinks=follow_symlinks):
children = source.iterdir()
target.mkdir(exist_ok=dirs_exist_ok)
for child in children:
if not (ignore and ignore(child)):
stack.append((child, target.joinpath(child.name)))
if preserve_metadata:
source._copy_metadata(target)
else:
source._copy_data(target)
if preserve_metadata:
# Metadata types supported by both source and target.
keys = source._readable_metadata & target._writable_metadata
if keys:
metadata = source._read_metadata(keys, follow_symlinks=follow_symlinks)
target._write_metadata(metadata, follow_symlinks=follow_symlinks)
if preserve_metadata:
source._copy_metadata(target)
except OSError as err:
on_error(err)

Expand Down
6 changes: 3 additions & 3 deletions Lib/pathlib/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,9 @@ def _copy_data(self, target):
try:
target = os.fspath(target)
except TypeError:
if isinstance(target, PathBase):
return PathBase._copy_data(self, target)
raise
if not isinstance(target, PathBase):
raise
PathBase._copy_data(self, target)
else:
copyfile(os.fspath(self), target)

Expand Down

0 comments on commit 017dd86

Please sign in to comment.