GH-89727: Partially fix `shutil.rmtree()` recursion error on deep tre… · python/cpython@a150679

GitHub

@@ -606,37 +606,21 @@ def _rmtree_islink(st):

606606607607# version vulnerable to race conditions

608608def_rmtree_unsafe(path, onexc):

609-try:

610-withos.scandir(path) asscandir_it:

611-entries=list(scandir_it)

612-exceptFileNotFoundError:

613-return

614-exceptOSErroraserr:

615-onexc(os.scandir, path, err)

616-entries= []

617-forentryinentries:

618-fullname=entry.path

619-try:

620-is_dir=entry.is_dir(follow_symlinks=False)

621-exceptFileNotFoundError:

622-continue

623-exceptOSError:

624-is_dir=False

625-626-ifis_dirandnotentry.is_junction():

609+defonerror(err):

610+ifnotisinstance(err, FileNotFoundError):

611+onexc(os.scandir, err.filename, err)

612+results=os.walk(path, topdown=False, onerror=onerror, followlinks=os._walk_symlinks_as_files)

613+fordirpath, dirnames, filenamesinresults:

614+fornameindirnames:

615+fullname=os.path.join(dirpath, name)

627616try:

628-ifentry.is_symlink():

629-# This can only happen if someone replaces

630-# a directory with a symlink after the call to

631-# os.scandir or entry.is_dir above.

632-raiseOSError("Cannot call rmtree on a symbolic link")

617+os.rmdir(fullname)

633618exceptFileNotFoundError:

634619continue

635620exceptOSErroraserr:

636-onexc(os.path.islink, fullname, err)

637-continue

638-_rmtree_unsafe(fullname, onexc)

639-else:

621+onexc(os.rmdir, fullname, err)

622+fornameinfilenames:

623+fullname=os.path.join(dirpath, name)

640624try:

641625os.unlink(fullname)

642626exceptFileNotFoundError: