Commits

Antoine Pitrou committed b223e96

Fix #10: Path.open() now sets the same file permissions as the built-in open(), when creating a file.

Comments (0)

Files changed (2)

     def _raise_closed(self):
         raise ValueError("I/O operation on closed path")
 
-    def _opener(self, name, flags, mode=0o777):
+    def _opener(self, name, flags, mode=0o666):
         # A stub for the opener argument to built-in open()
         return self._accessor.open(self, flags, mode)
 
         else:
             return io.open(str(self), mode, buffering, encoding, errors, newline)
 
-    def touch(self, mode=0o777, exist_ok=True):
+    def touch(self, mode=0o666, exist_ok=True):
         """
         Create this file with the given access mode, if it doesn't exist.
         """
 import os
 import errno
 import pathlib
+import shutil
+import stat
 import sys
-import shutil
 import tempfile
 import unittest
 from contextlib import contextmanager
         self.assertIs(False, p['foo'].exists())
         self.assertIs(False, P('/xyzzy').exists())
 
-    def test_open(self):
+    def test_open_common(self):
         p = self.cls(BASE)
         with p['fileA'].open('r') as f:
             self.assertIsInstance(f, io.TextIOBase)
         self.assertEqual(os.stat(r).st_size, size)
         self.assertFileNotFound(q.restat)
 
-    def test_touch(self):
+    def test_touch_common(self):
         P = self.cls(BASE)
         p = P['newfileA']
         self.assertFalse(p.exists())
         p.touch(mode=0o700, exist_ok=False)
         self.assertTrue(p.exists())
         self.assertRaises(OSError, p.touch, exist_ok=False)
-        # XXX better test `mode` arg
 
     def test_mkdir(self):
         P = self.cls(BASE)
         with self.assertRaises(ValueError):
             print(path.resolve())
 
+    def test_open_mode(self):
+        old_mask = os.umask(0)
+        self.addCleanup(os.umask, old_mask)
+        p = self.cls(BASE)
+        with p['new_file'].open('wb'):
+            pass
+        st = os.stat(join('new_file'))
+        self.assertEqual(stat.S_IMODE(st.st_mode), 0o666)
+        os.umask(0o022)
+        with p['other_new_file'].open('wb'):
+            pass
+        st = os.stat(join('other_new_file'))
+        self.assertEqual(stat.S_IMODE(st.st_mode), 0o644)
+
+    def test_touch_mode(self):
+        old_mask = os.umask(0)
+        self.addCleanup(os.umask, old_mask)
+        p = self.cls(BASE)
+        p['new_file'].touch()
+        st = os.stat(join('new_file'))
+        self.assertEqual(stat.S_IMODE(st.st_mode), 0o666)
+        os.umask(0o022)
+        p['other_new_file'].touch()
+        st = os.stat(join('other_new_file'))
+        self.assertEqual(stat.S_IMODE(st.st_mode), 0o644)
+        p['masked_new_file'].touch(mode=0o750)
+        st = os.stat(join('masked_new_file'))
+        self.assertEqual(stat.S_IMODE(st.st_mode), 0o750)
+
     @with_symlinks
     def test_resolve_loop(self):
         # Loop detection for broken symlinks under POSIX
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.