diff options
-rw-r--r-- | CHANGES.md | 8 | ||||
-rw-r--r-- | docs/modules.rst | 2 | ||||
-rw-r--r-- | pyfakefs/fake_file.py | 5 | ||||
-rw-r--r-- | pyfakefs/fake_filesystem.py | 24 | ||||
-rw-r--r-- | pyfakefs/fake_os.py | 23 | ||||
-rw-r--r-- | pyfakefs/helpers.py | 10 | ||||
-rw-r--r-- | pyfakefs/tests/fake_filesystem_shutil_test.py | 4 | ||||
-rw-r--r-- | pyfakefs/tests/fake_os_test.py | 32 |
8 files changed, 95 insertions, 13 deletions
@@ -3,9 +3,17 @@ The released versions correspond to PyPI releases. ## Unreleased +### Changes +* Made the user and group IDs accessible via dedicated ``get_uid`` and ``get_gid`` + functions (for symmetry to ``set_uid`` / ``set_gid``) + ### Fixes * The test fixture is now included in the source distribution and installed with the package. +* Some public constants in `fake_filesystem` that had been moved to `helpers` are + made accessible from there again (see [#809](../../issues/809)). +* Add missing fake implementations for `os.getuid` and `os.getgid` (Posix only) + ## [Version 5.2.1](https://pypi.python.org/pypi/pyfakefs/5.2.1) (2023-04-11) Support for latest Python 3.12 version. diff --git a/docs/modules.rst b/docs/modules.rst index 420d7ec..75c96bf 100644 --- a/docs/modules.rst +++ b/docs/modules.rst @@ -7,7 +7,7 @@ Public Modules and Classes Fake filesystem module ---------------------- .. automodule:: pyfakefs.helpers - :members: set_uid, set_gid, reset_ids, is_root + :members: get_uid, set_uid, get_gid, set_gid, reset_ids, is_root Fake filesystem classes ----------------------- diff --git a/pyfakefs/fake_file.py b/pyfakefs/fake_file.py index 4158a0b..0a866b1 100644 --- a/pyfakefs/fake_file.py +++ b/pyfakefs/fake_file.py @@ -159,7 +159,10 @@ class FakeFile: self._side_effect: Optional[Callable] = side_effect self.name: AnyStr = name # type: ignore[assignment] self.stat_result = FakeStatResult( - filesystem.is_windows_fs, helpers.USER_ID, helpers.GROUP_ID, helpers.now() + filesystem.is_windows_fs, + helpers.get_uid(), + helpers.get_gid(), + helpers.now(), ) if st_mode >> 12 == 0: st_mode |= S_IFREG diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 7a5c6b5..0b85e77 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -159,10 +159,19 @@ if sys.platform != "win32": PatchMode = fake_io.PatchMode is_root = helpers.is_root +get_uid = helpers.get_uid set_uid = helpers.set_uid +get_gid = helpers.get_gid set_gid = helpers.set_gid reset_ids = helpers.reset_ids +PERM_READ = helpers.PERM_READ +PERM_WRITE = helpers.PERM_WRITE +PERM_EXE = helpers.PERM_EXE +PERM_DEF = helpers.PERM_DEF +PERM_DEF_FILE = helpers.PERM_DEF_FILE +PERM_ALL = helpers.PERM_ALL + class FakeFilesystem: """Provides the appearance of a real directory tree for unit testing. @@ -735,7 +744,7 @@ class FakeFilesystem: times: Optional[Tuple[Union[int, float], Union[int, float]]] = None, *, ns: Optional[Tuple[int, int]] = None, - follow_symlinks: bool = True + follow_symlinks: bool = True, ) -> None: """Change the access and modified times of a file. @@ -1620,10 +1629,10 @@ class FakeFilesystem: @staticmethod def _can_read(target, owner_can_read): - if target.st_uid == helpers.USER_ID: + if target.st_uid == helpers.get_uid(): if owner_can_read or target.st_mode & 0o400: return True - if target.st_gid == helpers.GROUP_ID: + if target.st_gid == get_gid(): if target.st_mode & 0o040: return True return target.st_mode & 0o004 @@ -2914,5 +2923,14 @@ def _run_doctest() -> TestResults: return doctest.testmod(pyfakefs.fake_filesystem) +def __getattr__(name): + # backwards compatibility for read access to globals moved to helpers + if name == "USER_ID": + return helpers.USER_ID + if name == "GROUP_ID": + return helpers.GROUP_ID + raise AttributeError(f"No attribute {name!r}.") + + if __name__ == "__main__": _run_doctest() diff --git a/pyfakefs/fake_os.py b/pyfakefs/fake_os.py index 912fd31..a28939d 100644 --- a/pyfakefs/fake_os.py +++ b/pyfakefs/fake_os.py @@ -65,6 +65,8 @@ from pyfakefs.helpers import ( PERM_EXE, PERM_DEF, is_root, + get_uid, + get_gid, ) if TYPE_CHECKING: @@ -134,6 +136,11 @@ class FakeOsModule: "removexattr", "setxattr", ] + if sys.platform != "win32": + _dir += [ + "getgid", + "getuid", + ] if use_scandir: _dir += ["scandir"] return _dir @@ -1272,6 +1279,22 @@ class FakeOsModule: return written return 0 + def getuid(self) -> int: + """Returns the user id set in the fake filesystem. + If not changed using ``set_uid``, this is the uid of the real system. + """ + if self.filesystem.is_windows_fs: + raise NameError("name 'getuid' is not defined") + return get_uid() + + def getgid(self) -> int: + """Returns the group id set in the fake filesystem. + If not changed using ``set_gid``, this is the gid of the real system. + """ + if self.filesystem.is_windows_fs: + raise NameError("name 'getgid' is not defined") + return get_gid() + def fake_functions(self, original_functions) -> Set: functions = set() for fn in original_functions: diff --git a/pyfakefs/helpers.py b/pyfakefs/helpers.py index 8e32b3a..de4a62a 100644 --- a/pyfakefs/helpers.py +++ b/pyfakefs/helpers.py @@ -44,6 +44,11 @@ else: GROUP_ID = os.getgid() +def get_uid() -> int: + """Get the global user id. Same as ``os.getuid()``""" + return USER_ID + + def set_uid(uid: int) -> None: """Set the global user id. This is used as st_uid for new files and to differentiate between a normal user and the root user (uid 0). @@ -56,6 +61,11 @@ def set_uid(uid: int) -> None: USER_ID = uid +def get_gid() -> int: + """Get the global group id. Same as ``os.getgid()``""" + return GROUP_ID + + def set_gid(gid: int) -> None: """Set the global group id. This is only used to set st_gid for new files, no permission checks are performed. diff --git a/pyfakefs/tests/fake_filesystem_shutil_test.py b/pyfakefs/tests/fake_filesystem_shutil_test.py index e1bfab1..a3b4ae3 100644 --- a/pyfakefs/tests/fake_filesystem_shutil_test.py +++ b/pyfakefs/tests/fake_filesystem_shutil_test.py @@ -25,7 +25,7 @@ import unittest from pathlib import Path from pyfakefs import fake_filesystem_unittest -from pyfakefs.helpers import USER_ID, set_uid, is_root +from pyfakefs.helpers import get_uid, set_uid, is_root from pyfakefs.tests.test_utils import RealFsTestMixin is_windows = sys.platform == "win32" @@ -39,7 +39,7 @@ class RealFsTestCase(fake_filesystem_unittest.TestCase, RealFsTestMixin): def setUp(self): RealFsTestMixin.setUp(self) self.cwd = os.getcwd() - self.uid = USER_ID + self.uid = get_uid() set_uid(1000) if not self.use_real_fs(): self.setUpPyfakefs() diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py index dc83649..484443c 100644 --- a/pyfakefs/tests/fake_os_test.py +++ b/pyfakefs/tests/fake_os_test.py @@ -21,7 +21,7 @@ import stat import sys import unittest -from pyfakefs.helpers import IN_DOCKER, IS_PYPY, GROUP_ID, USER_ID +from pyfakefs.helpers import IN_DOCKER, IS_PYPY, get_uid, get_gid from pyfakefs import fake_filesystem, fake_os, fake_open, fake_file from pyfakefs.fake_filesystem import ( @@ -5403,6 +5403,26 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase): else: self.os.chmod(path, mode) + def test_getuid(self): + self.skip_real_fs() # won't change user in real fs + self.check_posix_only() + uid = self.os.getuid() + set_uid(uid + 10) + self.assertEqual(uid + 10, self.os.getuid()) + self.assertEqual(uid + 10, get_uid()) + set_uid(uid) + self.assertEqual(uid, self.os.getuid()) + + def test_getgid(self): + self.skip_real_fs() # won't change group in real fs + self.check_posix_only() + gid = self.os.getgid() + set_gid(gid + 10) + self.assertEqual(gid + 10, self.os.getgid()) + self.assertEqual(gid + 10, get_gid()) + set_gid(gid) + self.assertEqual(gid, self.os.getgid()) + def test_listdir_unreadable_dir(self): if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.listdir, self.dir_path) @@ -5417,7 +5437,7 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase): 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 + user_id = get_uid() set_uid(user_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o600) @@ -5431,7 +5451,7 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase): def test_listdir_group_readable_dir_from_other_user(self): self.skip_real_fs() # won't change user in real fs - user_id = USER_ID + user_id = get_uid() set_uid(user_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o660) @@ -5442,7 +5462,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 + group_id = self.os.getgid() set_gid(group_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o060) @@ -5456,7 +5476,7 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase): def test_listdir_other_readable_dir_from_other_group(self): self.skip_real_fs() # won't change user in real fs - group_id = GROUP_ID + group_id = get_gid() set_gid(group_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o004) @@ -5489,7 +5509,7 @@ class FakeOsUnreadableDirTest(FakeOsModuleTestBase): def test_remove_unreadable_dir_from_other_user(self): self.skip_real_fs() # won't change user in real fs - user_id = USER_ID + user_id = get_uid() set_uid(user_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o000) |