GH-73991: Add pathlib.Path.rmtree() (#119060)

Add a `Path.rmtree()` method that removes an entire directory tree, like
`shutil.rmtree()`. The signature of the optional *on_error* argument
matches the `Path.walk()` argument of the same name, but differs from the
*onexc* and *onerror* arguments to `shutil.rmtree()`. Consistency within
pathlib is probably more important.

In the private pathlib ABCs, we add an implementation based on `walk()`.

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Barney Gale 2024-07-20 21:14:13 +01:00 committed by GitHub
parent 8db5f48007
commit 094375b9b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 448 additions and 5 deletions

View file

@ -915,6 +915,47 @@ class PathBase(PurePathBase):
"""
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")
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)
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.