Title: Add an "onitem" callback parameter to shutil.rmtree()
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.9, Python 3.8, Python 3.7
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: Jeffrey.Kintscher, christian.heimes, giampaolo.rodola, josh.r, max, paul.moore, riccardomurri, serhiy.storchaka, steve.dower, tarek, tim.golden, zach.ware
Priority: normal Keywords: patch

Created on 2019-06-21 19:25 by Jeffrey.Kintscher, last changed 2019-07-03 20:08 by Jeffrey.Kintscher. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 14419 open Jeffrey.Kintscher, 2019-06-27 02:23
Messages (5)
msg346245 - (view) Author: Jeffrey Kintscher (Jeffrey.Kintscher) * Date: 2019-06-21 19:25
Add an "onitem" callback paramter to shutil.rmtree() that, if provided, gets called for each directory entry as it is encountered.  This allows the caller to perform any required special handling of individual directory entries (e.g. unmounting a mount point, closing a file, shutting down a named pipe, etc.) before rmtree() attempts to remove them.

This enhancement is related to issue #36422.
msg346719 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2019-06-27 08:43
I am not sure I understand the use case. Other than "unmounting a mount point" the other scenarios look unrealistic to me and also require a fd instead of a path. Also, if you want to unmount a path you can do so via *onerror* instead (unmount + delete). Pre-emptively checking if you have the permission to do something is sort of unpythonic and racy.
msg346805 - (view) Author: Jeffrey Kintscher (Jeffrey.Kintscher) * Date: 2019-06-28 07:10
Yes, onerror allows you to delete an undeletable item.  But, in the case of a mount point, the contents of the mounted filesystem get deleted *before* the mount point triggers onerror.  This is the case described in issue #36422.

The behavior provided by onitem allows you to provide a callback that can check for specific paths that may require special handling.  This is especially useful if the onitem callback is also added to tempfile.TemporaryDirectory().

My PR handles a missing onitem argument the same way onerror is handled by providing a do-nothing stub function:

if onitem is None:
    def onitem(*args):

I don't know enough about CPython internals to tell the performance differences between such a stub function and wrapping each call to onitem in an "if" block.
msg346806 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2019-06-28 08:01
I'm with Giampaolo.

I'm also concerned that the new callback will make the rmtree function too complicated. It's not a one-size-fits-all solution, but it covers most uses cases.
msg346879 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2019-06-29 12:00
I'm gonna reject this one, sorry Jeffrey. Reasons given in also apply here.
Date User Action Args
2019-07-03 20:08:37Jeffrey.Kintschersetresolution: rejected
2019-07-03 20:08:22Jeffrey.Kintschersetresolution: rejected -> (no value)
versions: + Python 3.7, Python 3.8
2019-06-29 12:00:11giampaolo.rodolasetstatus: open -> closed
resolution: rejected
messages: + msg346879

stage: patch review -> resolved
2019-06-28 08:01:17christian.heimessetnosy: + christian.heimes

messages: + msg346806
versions: - Python 3.7, Python 3.8
2019-06-28 07:10:27Jeffrey.Kintschersetmessages: + msg346805
versions: + Python 3.7, Python 3.8
2019-06-27 08:43:47giampaolo.rodolasetmessages: + msg346719
versions: - Python 3.7, Python 3.8
2019-06-27 02:23:27Jeffrey.Kintschersetkeywords: + patch
stage: patch review
pull_requests: + pull_request14232
2019-06-21 19:41:57Jeffrey.Kintschersetversions: + Python 3.7, Python 3.8
2019-06-21 19:36:47Jeffrey.Kintschersetnosy: + paul.moore, giampaolo.rodola, tim.golden, tarek, max, zach.ware, serhiy.storchaka, riccardomurri, steve.dower, josh.r
2019-06-21 19:25:52Jeffrey.Kintschercreate