Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2020-11-16.09:54:11.492>labels= ['type-feature', 'library', '3.11']
title='Restore os.makedirs ability to apply mode to all directories created'updated_at=<Date2021-11-22.21:16:30.185>user='https://github.com/gpshead'
os.makedirs used to pass its mode argument on down recursively so that every level of directory it created would have the specified permissions.
That was removed in Python 3.7 as https://bugs.python.org/issue19930 as if it were a mis-feature. Maybe it was in one situation, but it was also a desirable *feature*. It wasn't a bug.
We've got 15 year old code depending on that and the only solution for it to work on Python 3.7-3.9 is to reimplement recursive directory creation. :(
This feature needs to be brought back. Rather than flip flop on the API, adding an flag to indicate if the permissions should be applied recursively or not seems like the best way forward.
The "workaround" documented in the above bug is invalid. umask cannot be used to control the intermediate directory creation permissions as that is a process wide global that would impact other threads or signal handlers. umask also cannot be used as umask does not allow setting of special bits such as stat.S_ISVTX.
result: Our old os.makedirs() code that tried to set the sticky bit (ISVTX) on all directories now fails to set it at all levels.
@hugovk as 3.15 release manager: Would you consider the fix for this adding a new parent_mode=None keyword only argument to os.makedirs() and for use in pathlib.mkdir(..., parents=True) viable as a feature to add to 3.15? It is security related and we've had it open for ages as it exists to fix a it is security regression that shipped in 3.7. it doesn't change behavior, just adds a new optional keyword argument. I could make the argument that we should backport it to others given the security workarounds things like Django have had to adopt as a result (but they'll need to carry those anyways so probably best not to)... but adding it to 3.15beta2 seems uncontroversial and not likely to trip anyone up and avoids delaying yet another year. - #150011
Activity
gpshead commented on Nov 16, 2020
os.makedirs used to pass its mode argument on down recursively so that every level of directory it created would have the specified permissions.
That was removed in Python 3.7 as https://bugs.python.org/issue19930 as if it were a mis-feature. Maybe it was in one situation, but it was also a desirable *feature*. It wasn't a bug.
We've got 15 year old code depending on that and the only solution for it to work on Python 3.7-3.9 is to reimplement recursive directory creation. :(
This feature needs to be brought back. Rather than flip flop on the API, adding an flag to indicate if the permissions should be applied recursively or not seems like the best way forward.
The "workaround" documented in the above bug is invalid. umask cannot be used to control the intermediate directory creation permissions as that is a process wide global that would impact other threads or signal handlers. umask also cannot be used as umask does not allow setting of special bits such as stat.S_ISVTX.
result: Our old os.makedirs() code that tried to set the sticky bit (ISVTX) on all directories now fails to set it at all levels.
gpshead commented on Nov 16, 2020
For consistency, pathlib.Path.mkdir should also gain this option.
serhiy-storchaka commented on Nov 16, 2020
Alternatively we can add an optional argument for the mode of intermediate directories.
tiran commented on Nov 16, 2020
+1 for restoring the feature
+0 for Serhiy's proposal iff intermediate_mode defaults to the value of mode:
20 remaining items
gpshead commented on May 18, 2026
@hugovk as 3.15 release manager: Would you consider the fix for this adding a new parent_mode=None keyword only argument to os.makedirs() and for use in pathlib.mkdir(..., parents=True) viable as a feature to add to 3.15? It is security related and we've had it open for ages as it exists to fix a it is security regression that shipped in 3.7. it doesn't change behavior, just adds a new optional keyword argument. I could make the argument that we should backport it to others given the security workarounds things like Django have had to adopt as a result (but they'll need to carry those anyways so probably best not to)... but adding it to 3.15beta2 seems uncontroversial and not likely to trip anyone up and avoids delaying yet another year. - #150011
hugovk commented on May 18, 2026
Yes, that's fine for 3.15beta2.
Fixed CVE-2026-25674 -- Prevented potentially incorrect permissions o…
pythongh-86533: Clarify parent_mode umask docs and harden makedirs/mk…
gh-86533: Restore os.makedirs() ability to apply *mode* recursively (G…
pythongh-86533: Make Path.mkdir parent_mode tests umask-independent
Merge branch 'main' into pythongh-86533-fix-mkdir-test-umask
gh-86533: Make Path.mkdir parent_mode tests umask-independent (#150040)
[3.15] gh-86533: Restore os.makedirs() ability to apply *mode* recurs…
gpshead commented on May 19, 2026
thanks! this ships in 3.15beta2 onwards.
Fixed CVE-2026-25674 -- Prevented potentially incorrect permissions o…