This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Add shutil.chowntree
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.6
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Low.Kian.Seong, Tigger.Level-5, YoSTEALTH, berker.peksag, eric.araujo, eric.smith, ezio.melotti, giampaolo.rodola, ncoghlan, orsenthil, pitrou, r.david.murray, sedrubal, socketpair, vstinner
Priority: normal Keywords: patch

Created on 2011-09-23 09:24 by Low.Kian.Seong, last changed 2022-04-11 14:57 by admin.

File name Uploaded Description Edit Tigger.Level-5, 2011-09-25 00:41 chowntree function
chowntree.patch Tigger.Level-5, 2011-12-26 01:16
Messages (14)
msg144439 - (view) Author: Low Kian Seong (Low.Kian.Seong) Date: 2011-09-23 09:24
Currently shutils chown still can't do a recursive chown. It would be nice to have this instead of having to do the looping dance we put our selves through each time we need recursion. Ruby's FileUtils already have this.
msg144440 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2011-09-23 09:58
See also issue 12191, where there was a brief discussion of this.
msg144452 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-09-23 16:34
Wasn’t there a python-ideas discussion on this?  If someone could find a link and summarize use cases it would be great.
msg144453 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2011-09-23 16:39
msg144464 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-09-23 17:11
Following Nick’s opinion in the thread, I’d prefer a distinct function.
msg144514 - (view) Author: Tigger Level-5 (Tigger.Level-5) Date: 2011-09-25 00:41
First time posting, how about something like this. Just added a os.walk method to do the chown recursively.
msg147090 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-11-05 16:01
See also #13229.
msg147091 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-11-05 16:01
Tigger: Could you provide a patch for Python 3.3? (more info at
msg150251 - (view) Author: Tigger Level-5 (Tigger.Level-5) Date: 2011-12-26 01:16
Hi Éric,

Apologies for the late response, attached is the patch. Let me know if
I need any changes or anything else.


On Sat, Nov 5, 2011 at 11:01 AM, Éric Araujo <> wrote:
> Éric Araujo <> added the comment:
> Tigger: Could you provide a patch for Python 3.3? (more info at
> ----------
> _______________________________________
> Python tracker <>
> <>
> _______________________________________
msg150739 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-01-06 16:42
Thanks for the patch.  Before you do any more work, do other core developers agree that this function is a good addition or is it obsoleted by the generic improved-walk-with-callback that Nick is working on?


I don’t think the note directives are needed.  The doc is not big, I assume people will read all of it and see the caveats.  (I’ll also want to group some small paragraphs.)


+def chowntree(path, user=None, group=None, followlinks=False):
+ [...]
+    The dictionary _modified_items, will keep track of the old ownership details,
What _modified_items dictionary?

Apart from a few stylistic violations which can be fixed by the committer, the function looks good.


Looks good and needs more tests.  Currently it only calls chowntree on a directory without children, so it does not test that the chown is indeed recursive.
msg150791 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2012-01-07 12:12
I believe the current "check_chown" could be passed by a no-op (since the file will be owned by the current user even *before* the call to chowntree). Testing this properly is actually rather difficult (since the only uid and gid we can rely on are those of the current process).

More significantly, I don't agree with the proposed error handling (i.e. attempting to roll back to the original state). Instead, I think it would be more appropriate to follow the rmtree ignore_errors/onerror style so that uses can either unconditionally ignore errors (including dir listing errors) or else tailor the error handling themselves. Any custom error handling should also cover the actual chown operation, not just directory listing errors inside os.walk.

I think, like walkdir itself, there's enough under the hood here that the idea requires some baking time outside the standard library. How do you feel about migrating this discussion over to the walkdir issue tracker as a higher level API proposal there? (

I had a couple of other minor comments, although they're largely irrelevant given the more significant comments above:

There's a gratuitous inconsistency in the type-checking for uid/gid (one uses "isinstance(uid, str)", the other "not isinstance(gid, int)". Neither is a particular good check for the "None, integer or string" case anyway. It would be better to just try the following in order:

- "is None"
- operator.index
- _get_uid/gid (as appropriate)

The dict initialisation and error handler definition may as well move inside the if statement.
msg255869 - (view) Author: (YoSTEALTH) * Date: 2015-12-04 17:00
Can this chowntree() function proposed here be implemented? It would have saved me a bunch of time and its a good feature to have.
msg256325 - (view) Author: Марк Коренберг (socketpair) * Date: 2015-12-13 17:36
Instead, it may be desirable to implement wrapper over ow.walk() that apply given function to every member.


recursive_apply('/some/dir', lambda x: os.chown(x, 42, 42))
msg256326 - (view) Author: Марк Коренберг (socketpair) * Date: 2015-12-13 17:42
note, that there are many other usecases for that function, like chattr, chmod g+w, touch and so on.

But I'm personally consider this will bloat python library, since everyone can write it's own cycle over os.walk() in his program.

Also, chown itself is allowed only for superuser (although chgrp is allowed in some cases to generic user), so this is very rare usecase, as I think.
Date User Action Args
2022-04-11 14:57:21adminsetgithub: 57242
2021-08-27 16:27:56sedrubalsetnosy: + sedrubal
2015-12-13 17:42:36socketpairsetmessages: + msg256326
2015-12-13 17:36:20socketpairsetnosy: + socketpair
messages: + msg256325
2015-12-13 16:16:05berker.peksagsetnosy: + berker.peksag
stage: patch review

versions: + Python 3.6, - Python 3.3
2015-12-04 17:00:18YoSTEALTHsetnosy: + r.david.murray, YoSTEALTH
messages: + msg255869
2015-12-03 23:40:19r.david.murraylinkissue25790 superseder
2012-01-07 12:12:37ncoghlansetmessages: + msg150791
2012-01-06 16:42:41eric.araujosetnosy: + ncoghlan, pitrou, vstinner, giampaolo.rodola
messages: + msg150739
2011-12-26 01:16:21Tigger.Level-5setfiles: + chowntree.patch
keywords: + patch
messages: + msg150251
2011-11-05 16:01:40eric.araujosetmessages: + msg147091
2011-11-05 16:01:15eric.araujosetmessages: + msg147090
2011-10-27 13:00:55orsenthilsetnosy: + orsenthil
2011-09-25 00:41:52Tigger.Level-5setfiles: +
nosy: + Tigger.Level-5
messages: + msg144514

2011-09-23 17:11:36eric.araujosetmessages: + msg144464
title: Support recursivity in shutil.chown -> Add shutil.chowntree
2011-09-23 16:39:52ezio.melottisetnosy: + ezio.melotti
messages: + msg144453
2011-09-23 16:34:56eric.araujosetnosy: + eric.araujo
title: recursive chown for shutils -> Support recursivity in shutil.chown
messages: + msg144452

versions: + Python 3.3, - Python 2.7
type: enhancement
2011-09-23 09:58:48eric.smithsetnosy: + eric.smith
messages: + msg144440
2011-09-23 09:24:09Low.Kian.Seongcreate