diff options
author | mrbean-bremen <hansemrbean@googlemail.com> | 2023-01-21 20:43:11 +0100 |
---|---|---|
committer | mrbean-bremen <mrbean-bremen@users.noreply.github.com> | 2023-01-24 20:07:43 +0100 |
commit | 783afc94a5a6de885b0a02622c7c8b75d9832918 (patch) | |
tree | 3772f3ca0ea6d7e867dc9c5f66d6dd1a784dbdf6 /pyfakefs | |
parent | 99957b22413a5f0ab09259fbf65347497ab35b19 (diff) | |
download | pyfakefs-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.py | 14 | ||||
-rw-r--r-- | pyfakefs/tests/fake_os_test.py | 24 | ||||
-rw-r--r-- | pyfakefs/tests/fake_pathlib_test.py | 22 |
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) |