]> granicus.if.org Git - python/commitdiff
bpo-19930: The mode argument of os.makedirs() no longer affects the file (#799)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 24 Mar 2017 11:27:42 +0000 (13:27 +0200)
committerGitHub <noreply@github.com>
Fri, 24 Mar 2017 11:27:42 +0000 (13:27 +0200)
permission bits of newly-created intermediate-level directories.

Doc/library/os.rst
Doc/whatsnew/3.7.rst
Lib/os.py
Lib/test/test_os.py
Misc/NEWS

index 7d2ec6073484c2761354bc77738a06ff40ef0c57..69dd5c45677345933dcca7469a24973afd3f930a 100644 (file)
@@ -1741,8 +1741,11 @@ features:
    Recursive directory creation function.  Like :func:`mkdir`, but makes all
    intermediate-level directories needed to contain the leaf directory.
 
-   The *mode* parameter is passed to :func:`mkdir`; see :ref:`the mkdir()
-   description <mkdir_modebits>` for how it is interpreted.
+   The *mode* parameter is passed to :func:`mkdir` for creating the leaf
+   directory; see :ref:`the mkdir() description <mkdir_modebits>` for how it
+   is interpreted.  To set the file permission bits of any newly-created parent
+   directories you can set the umask before invoking :func:`makedirs`.  The
+   file permission bits of existing parent directories are not changed.
 
    If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if the
    target directory already exists.
@@ -1767,6 +1770,10 @@ features:
    .. versionchanged:: 3.6
       Accepts a :term:`path-like object`.
 
+   .. versionchanged:: 3.7
+      The *mode* argument no longer affects the file permission bits of
+      newly-created intermediate-level directories.
+
 
 .. function:: mkfifo(path, mode=0o666, *, dir_fd=None)
 
index 882d6a27f7e26b83672d64e6e12452b6df5ba99b..b69f452b1331040d29c16bfe004d0ae1c9b3516e 100644 (file)
@@ -247,6 +247,13 @@ Changes in the Python API
   and module are affected by this change.
   (Contributed by INADA Naoki and Eugene Toder in :issue:`29463`.)
 
+* The *mode* argument of :func:`os.makedirs` no longer affects the file
+  permission bits of newly-created intermediate-level directories.
+  To set their file permission bits you can set the umask before invoking
+  ``makedirs()``.
+  (Contributed by Serhiy Storchaka in :issue:`19930`.)
+
+
 CPython bytecode changes
 ------------------------
 
index 18ec124b29aacfd68809f69773747792a3508265..70857c7e7856204da2b844c3ebd700c08f4f8a9d 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -207,7 +207,7 @@ def makedirs(name, mode=0o777, exist_ok=False):
         head, tail = path.split(head)
     if head and tail and not path.exists(head):
         try:
-            makedirs(head, mode, exist_ok)
+            makedirs(head, exist_ok=exist_ok)
         except FileExistsError:
             # Defeats race condition when another thread created the path
             pass
index 5f302f6d0eead6a55eb14938fe72129b74b0c339..83932e64a0b94c35696d2ea1a198d51cd03a5e31 100644 (file)
@@ -1118,6 +1118,18 @@ class MakedirTests(unittest.TestCase):
                             'dir5', 'dir6')
         os.makedirs(path)
 
+    def test_mode(self):
+        with support.temp_umask(0o002):
+            base = support.TESTFN
+            parent = os.path.join(base, 'dir1')
+            path = os.path.join(parent, 'dir2')
+            os.makedirs(path, 0o555)
+            self.assertTrue(os.path.exists(path))
+            self.assertTrue(os.path.isdir(path))
+            if os.name != 'nt':
+                self.assertEqual(stat.S_IMODE(os.stat(path).st_mode), 0o555)
+                self.assertEqual(stat.S_IMODE(os.stat(parent).st_mode), 0o775)
+
     def test_exist_ok_existing_directory(self):
         path = os.path.join(support.TESTFN, 'dir1')
         mode = 0o777
index 8cc8b9f971f2bcb054ca2533ee06d341693f16ba..8003facf12229134f76a13cf0ab3f419dc87f257 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -287,6 +287,9 @@ Extension Modules
 Library
 -------
 
+- bpo-19930: The mode argument of os.makedirs() no longer affects the file
+  permission bits of newly-created intermediate-level directories.
+
 - bpo-29884: faulthandler: Restore the old sigaltstack during teardown.
   Patch by Christophe Zeitouny.