aboutsummaryrefslogtreecommitdiff
path: root/pyfakefs
diff options
context:
space:
mode:
authormrbean-bremen <hansemrbean@googlemail.com>2023-01-21 20:43:11 +0100
committermrbean-bremen <mrbean-bremen@users.noreply.github.com>2023-01-24 20:07:43 +0100
commit783afc94a5a6de885b0a02622c7c8b75d9832918 (patch)
tree3772f3ca0ea6d7e867dc9c5f66d6dd1a784dbdf6 /pyfakefs
parent99957b22413a5f0ab09259fbf65347497ab35b19 (diff)
downloadpyfakefs-783afc94a5a6de885b0a02622c7c8b75d9832918.tar.gz
Add "force_unix_mode" flag to FakeFilesystem.chmod
- makes it possible to simulate inaccessible paths under Windows - see #720
Diffstat (limited to 'pyfakefs')
-rw-r--r--pyfakefs/fake_filesystem.py14
-rw-r--r--pyfakefs/tests/fake_os_test.py24
-rw-r--r--pyfakefs/tests/fake_pathlib_test.py22
3 files changed, 47 insertions, 13 deletions
diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py
index a294ab5..ae5023f 100644
--- a/pyfakefs/fake_filesystem.py
+++ b/pyfakefs/fake_filesystem.py
@@ -1438,7 +1438,13 @@ class FakeFilesystem:
error_nr = errno.EINVAL if self.is_windows_fs else errno.ENOTDIR
self.raise_os_error(error_nr, entry_path)
- def chmod(self, path: AnyStr, mode: int, follow_symlinks: bool = True) -> None:
+ def chmod(
+ self,
+ path: AnyStr,
+ mode: int,
+ follow_symlinks: bool = True,
+ force_unix_mode: bool = False,
+ ) -> None:
"""Change the permissions of a file as encoded in integer mode.
Args:
@@ -1446,11 +1452,13 @@ class FakeFilesystem:
mode: (int) Permissions.
follow_symlinks: If `False` and `path` points to a symlink,
the link itself is affected instead of the linked object.
+ force_unix_mode: if True and run under Windows, the mode is not
+ adapted for Windows to allow making dirs unreadable
"""
file_object = self.resolve(
path, follow_symlinks, allow_fd=True, check_owner=True
)
- if self.is_windows_fs:
+ if self.is_windows_fs and not force_unix_mode:
if mode & PERM_WRITE:
file_object.st_mode = file_object.st_mode | 0o222
else:
@@ -2355,7 +2363,7 @@ class FakeFilesystem:
if follow_symlinks:
return self.get_object_from_normpath(
- self.resolve_path(file_path, check_read_perm),
+ self.resolve_path(file_path, allow_fd),
check_read_perm,
check_owner,
)
diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py
index d405b49..2ad28bb 100644
--- a/pyfakefs/tests/fake_os_test.py
+++ b/pyfakefs/tests/fake_os_test.py
@@ -5366,14 +5366,21 @@ class FakeExtendedAttributeTest(FakeOsModuleTestBase):
class FakeOsUnreadableDirTest(FakeOsModuleTestBase):
def setUp(self):
if self.use_real_fs():
- # make sure no dir is created if skipped
+ # unreadable dirs in Windows are only simulated
+ # and cannot be created in the real OS using file system
+ # functions only
self.check_posix_only()
super(FakeOsUnreadableDirTest, self).setUp()
- self.check_posix_only()
self.dir_path = self.make_path("some_dir")
self.file_path = self.os.path.join(self.dir_path, "some_file")
self.create_file(self.file_path)
- self.os.chmod(self.dir_path, 0o000)
+ self.chmod(self.dir_path, 0o000)
+
+ def chmod(self, path, mode):
+ if self.is_windows_fs:
+ self.filesystem.chmod(path, mode, force_unix_mode=True)
+ else:
+ self.os.chmod(path, mode)
def test_listdir_unreadable_dir(self):
if not is_root():
@@ -5382,12 +5389,13 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase):
self.assertEqual(["some_file"], self.os.listdir(self.dir_path))
def test_listdir_user_readable_dir(self):
- self.os.chmod(self.dir_path, 0o600)
+ self.chmod(self.dir_path, 0o600)
self.assertEqual(["some_file"], self.os.listdir(self.dir_path))
- self.os.chmod(self.dir_path, 0o000)
+ self.chmod(self.dir_path, 0o000)
def test_listdir_user_readable_dir_from_other_user(self):
self.skip_real_fs() # won't change user in real fs
+ self.check_posix_only()
user_id = USER_ID
set_uid(user_id + 1)
dir_path = self.make_path("dir1")
@@ -5412,6 +5420,7 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase):
def test_listdir_group_readable_dir_from_other_group(self):
self.skip_real_fs() # won't change user in real fs
+ self.check_posix_only()
group_id = GROUP_ID
set_gid(group_id + 1)
dir_path = self.make_path("dir1")
@@ -5438,9 +5447,9 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase):
self.assertEqual(0, self.os.stat(self.dir_path).st_mode & 0o666)
def test_chmod_unreadable_dir(self):
- self.os.chmod(self.dir_path, 0o666)
+ self.chmod(self.dir_path, 0o666)
self.assertEqual(0o666, self.os.stat(self.dir_path).st_mode & 0o666)
- self.os.chmod(self.dir_path, 0o000)
+ self.chmod(self.dir_path, 0o000)
self.assertEqual(0, self.os.stat(self.dir_path).st_mode & 0o666)
def test_stat_file_in_unreadable_dir(self):
@@ -5450,6 +5459,7 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase):
self.assertEqual(0, self.os.stat(self.file_path).st_size)
def test_remove_unreadable_dir(self):
+ self.check_posix_only()
dir_path = self.make_path("dir1")
self.create_dir(dir_path, perm=0o000)
self.assertTrue(self.os.path.exists(dir_path))
diff --git a/pyfakefs/tests/fake_pathlib_test.py b/pyfakefs/tests/fake_pathlib_test.py
index fad500a..fbbde04 100644
--- a/pyfakefs/tests/fake_pathlib_test.py
+++ b/pyfakefs/tests/fake_pathlib_test.py
@@ -29,7 +29,7 @@ from collections import namedtuple
from unittest import mock
from pyfakefs import fake_pathlib, fake_filesystem, fake_filesystem_unittest
-from pyfakefs.fake_filesystem import is_root
+from pyfakefs.fake_filesystem import is_root, OSType
from pyfakefs.helpers import IS_PYPY
from pyfakefs.tests.test_utils import RealFsTestMixin
@@ -762,7 +762,6 @@ class RealPathlibPathFileOperationTest(FakePathlibPathFileOperationTest):
return True
-@unittest.skipIf(sys.version_info < (3, 6), "path-like objects new in Python 3.6")
class FakePathlibUsageInOsFunctionsTest(RealPathlibTestCase):
"""Test that many os / os.path functions accept a path-like object
since Python 3.6. The functionality of these functions is tested
@@ -1121,7 +1120,6 @@ class RealPathlibUsageInOsFunctionsTest(FakePathlibUsageInOsFunctionsTest):
return True
-@unittest.skipIf(sys.version_info < (3, 6), "Path-like objects new in Python 3.6")
class FakeFilesystemPathLikeObjectTest(unittest.TestCase):
def setUp(self):
self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/")
@@ -1180,5 +1178,23 @@ class FakeFilesystemPathLikeObjectTest(unittest.TestCase):
)
+class FakeFilesystemChmodTest(fake_filesystem_unittest.TestCase):
+ def setUp(self) -> None:
+ self.setUpPyfakefs()
+
+ @unittest.skipIf(sys.platform != "win32", "Windows specific test")
+ def test_is_file_for_unreadable_dir_windows(self):
+ self.fs.os = OSType.WINDOWS
+ path = pathlib.Path("/foo/bar")
+ self.fs.create_file(path)
+ # normal chmod does not really set the mode to 0
+ self.fs.chmod("/foo", 0o000)
+ self.assertTrue(path.is_file())
+ # but it does in forced UNIX mode
+ self.fs.chmod("/foo", 0o000, force_unix_mode=True)
+ with self.assertRaises(PermissionError):
+ path.is_file()
+
+
if __name__ == "__main__":
unittest.main(verbosity=2)