mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
GH-125413: Add private pathlib.Path
method to write metadata (#130238)
Replace `WritablePath._copy_writer` with a new `_write_info()` method. This method allows the target of a `copy()` to preserve metadata. Replace `pathlib._os.CopyWriter` and `LocalCopyWriter` classes with new `copy_file()` and `copy_info()` functions. The `copy_file()` function uses `source_path.info` wherever possible to save on `stat()`s.
This commit is contained in:
parent
5ba69e747f
commit
b251d409f9
4 changed files with 122 additions and 174 deletions
|
@ -19,7 +19,11 @@ try:
|
|||
except ImportError:
|
||||
grp = None
|
||||
|
||||
from pathlib._os import LocalCopyWriter, PathInfo, DirEntryInfo, ensure_different_files
|
||||
from pathlib._os import (
|
||||
PathInfo, DirEntryInfo,
|
||||
ensure_different_files, ensure_distinct_paths,
|
||||
copy_file, copy_info,
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
@ -799,6 +803,12 @@ class Path(PurePath):
|
|||
with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f:
|
||||
return f.write(data)
|
||||
|
||||
def _write_info(self, info, follow_symlinks=True):
|
||||
"""
|
||||
Write the given PathInfo to this path.
|
||||
"""
|
||||
copy_info(info, self, follow_symlinks=follow_symlinks)
|
||||
|
||||
_remove_leading_dot = operator.itemgetter(slice(2, None))
|
||||
_remove_trailing_slash = operator.itemgetter(slice(-1))
|
||||
|
||||
|
@ -1083,8 +1093,6 @@ class Path(PurePath):
|
|||
target = self.with_segments(target)
|
||||
return target
|
||||
|
||||
_copy_writer = property(LocalCopyWriter)
|
||||
|
||||
def copy(self, target, follow_symlinks=True, dirs_exist_ok=False,
|
||||
preserve_metadata=False):
|
||||
"""
|
||||
|
@ -1092,13 +1100,8 @@ class Path(PurePath):
|
|||
"""
|
||||
if not hasattr(target, 'with_segments'):
|
||||
target = self.with_segments(target)
|
||||
|
||||
# Delegate to the target path's CopyWriter object.
|
||||
try:
|
||||
create = target._copy_writer._create
|
||||
except AttributeError:
|
||||
raise TypeError(f"Target is not writable: {target}") from None
|
||||
create(self, follow_symlinks, dirs_exist_ok, preserve_metadata)
|
||||
ensure_distinct_paths(self, target)
|
||||
copy_file(self, target, follow_symlinks, dirs_exist_ok, preserve_metadata)
|
||||
return target.joinpath() # Empty join to ensure fresh metadata.
|
||||
|
||||
def copy_into(self, target_dir, *, follow_symlinks=True,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue