GH-73991: Add `pathlib.Path.rmtree()` by barneygale · Pull Request #119060 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Doc/library/pathlib.rst
14 changes: 9 additions & 5 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,15 @@ os
pathlib
-------

* Add :meth:`pathlib.Path.copy`, which copies the content of one file to
another, like :func:`shutil.copyfile`.
(Contributed by Barney Gale in :gh:`73991`.)
* Add :meth:`pathlib.Path.copytree`, which copies one directory tree to
another.
* Add methods to :class:`pathlib.Path` to recursively copy or remove files:

* :meth:`~pathlib.Path.copy` copies the content of one file to another, like
:func:`shutil.copyfile`.
* :meth:`~pathlib.Path.copytree` copies one directory tree to another, like
:func:`shutil.copytree`.
* :meth:`~pathlib.Path.rmtree` recursively removes a directory tree, like
:func:`shutil.rmtree`.

(Contributed by Barney Gale in :gh:`73991`.)

pdb
Expand Down
41 changes: 41 additions & 0 deletions Lib/pathlib/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,47 @@ def rmdir(self):
"""
raise UnsupportedOperation(self._unsupported_msg('rmdir()'))

def rmtree(self, ignore_errors=False, on_error=None):
"""
Recursively delete this directory tree.

If *ignore_errors* is true, exceptions raised from scanning the tree
and removing files and directories are ignored. Otherwise, if
*on_error* is set, it will be called to handle the error. If neither
*ignore_errors* nor *on_error* are set, exceptions are propagated to
the caller.
"""
if ignore_errors:
def on_error(err):
pass
elif on_error is None:
def on_error(err):
raise err
try:
if self.is_symlink():
raise OSError("Cannot call rmtree on a symbolic link")
Comment thread
barneygale marked this conversation as resolved.
elif self.is_junction():
raise OSError("Cannot call rmtree on a junction")
results = self.walk(
on_error=on_error,
top_down=False, # Bottom-up so we rmdir() empty directories.
follow_symlinks=False)
for dirpath, dirnames, filenames in results:
for name in filenames:
try:
dirpath.joinpath(name).unlink()
except OSError as err:
on_error(err)
for name in dirnames:
try:
dirpath.joinpath(name).rmdir()
except OSError as err:
on_error(err)
Comment thread
barneygale marked this conversation as resolved.
self.rmdir()
except OSError as err:
err.filename = str(self)
on_error(err)

def owner(self, *, follow_symlinks=True):
"""
Return the login name of the file owner.
Expand Down
19 changes: 19 additions & 0 deletions Lib/pathlib/_local.py
Loading