GH-73991: Rework pathlib.Path.rmtree() into delete() (#122368)

Rename `pathlib.Path.rmtree()` to `delete()`, and add support for deleting
non-directories. This simplifies the interface for users, and nicely
complements the upcoming `move()` and `copy()` methods (which will also
accept any type of file.)
This commit is contained in:
Barney Gale 2024-08-07 01:34:44 +01:00 committed by GitHub
parent b5e142ba7c
commit 98dba73010
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 139 additions and 149 deletions

View file

@ -919,15 +919,15 @@ class PathBase(PurePathBase):
"""
raise UnsupportedOperation(self._unsupported_msg('rmdir()'))
def rmtree(self, ignore_errors=False, on_error=None):
def delete(self, ignore_errors=False, on_error=None):
"""
Recursively delete this directory tree.
Delete this file or directory (including all sub-directories).
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* is true, exceptions raised from scanning the
filesystem 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):
@ -935,14 +935,10 @@ class PathBase(PurePathBase):
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")
if self.is_dir(follow_symlinks=False):
results = self.walk(
on_error=on_error,
top_down=False, # Bottom-up so we rmdir() empty directories.
top_down=False, # So we rmdir() empty directories.
follow_symlinks=False)
for dirpath, dirnames, filenames in results:
for name in filenames:
@ -955,10 +951,15 @@ class PathBase(PurePathBase):
dirpath.joinpath(name).rmdir()
except OSError as err:
on_error(err)
self.rmdir()
delete_self = self.rmdir
else:
delete_self = self.unlink
try:
delete_self()
except OSError as err:
err.filename = str(self)
on_error(err)
delete.avoids_symlink_attacks = False
def owner(self, *, follow_symlinks=True):
"""