mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
GH-73991: Add pathlib.Path.copytree()
(#120718)
Add `pathlib.Path.copytree()` method, which recursively copies one directory to another. This differs from `shutil.copytree()` in the following respects: 1. Our method has a *follow_symlinks* argument, whereas shutil's has a *symlinks* argument with an inverted meaning. 2. Our method lacks something like a *copy_function* argument. It always uses `Path.copy()` to copy files. 3. Our method lacks something like a *ignore_dangling_symlinks* argument. Instead, users can filter out danging symlinks with *ignore*, or ignore exceptions with *on_error* 4. Our *ignore* argument is a callable that accepts a single path object, whereas shutil's accepts a path and a list of child filenames. 5. We add an *on_error* argument, which is a callable that accepts an `OSError` instance. (`Path.walk()` also accepts such a callable). Co-authored-by: Nice Zombies <nineteendo19d0@gmail.com>
This commit is contained in:
parent
bc37ac7b44
commit
35e998f560
6 changed files with 231 additions and 0 deletions
|
@ -815,6 +815,36 @@ class PathBase(PurePathBase):
|
|||
else:
|
||||
raise
|
||||
|
||||
def copytree(self, target, *, follow_symlinks=True, dirs_exist_ok=False,
|
||||
ignore=None, on_error=None):
|
||||
"""
|
||||
Recursively copy this directory tree to the given destination.
|
||||
"""
|
||||
if not isinstance(target, PathBase):
|
||||
target = self.with_segments(target)
|
||||
if on_error is None:
|
||||
def on_error(err):
|
||||
raise err
|
||||
stack = [(self, target)]
|
||||
while stack:
|
||||
source_dir, target_dir = stack.pop()
|
||||
try:
|
||||
sources = source_dir.iterdir()
|
||||
target_dir.mkdir(exist_ok=dirs_exist_ok)
|
||||
for source in sources:
|
||||
if ignore and ignore(source):
|
||||
continue
|
||||
try:
|
||||
if source.is_dir(follow_symlinks=follow_symlinks):
|
||||
stack.append((source, target_dir.joinpath(source.name)))
|
||||
else:
|
||||
source.copy(target_dir.joinpath(source.name),
|
||||
follow_symlinks=follow_symlinks)
|
||||
except OSError as err:
|
||||
on_error(err)
|
||||
except OSError as err:
|
||||
on_error(err)
|
||||
|
||||
def rename(self, target):
|
||||
"""
|
||||
Rename this path to the target path.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue