From f1ca2d8df0362811f785ab4d0da0377cbd9a2f2f Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Mon, 6 Jun 2022 18:18:36 +0200 Subject: [PATCH] Change pathlib.Path.owner()/group() to behave like real os - both methods now look up the real user/group name for the user/group id that is associated with the fake file - assumes a valid user and group id is set - closes #678 --- CHANGES.md | 8 ++++++-- pyfakefs/fake_pathlib.py | 14 ++++++++------ pyfakefs/tests/fake_pathlib_test.py | 29 ++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2aded265..a07e2b44 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,12 +8,16 @@ The released versions correspond to PyPi releases. longer officially supported by pyfakefs ** `os.stat_float_times` has been removed in Python 3.7 and is therefore no longer supported -* added some support for the upcoming Python version 3.11 - (see [#677](../../issues/677)) * under Windows, the root path is now effectively `C:\` instead of `\`; a path starting with `\` points to the current drive as in the real file system (see [#673](../../issues/673)) +* fake `pathlib.Path.owner()` and `pathlib.Path.group()` now behave like the + real methods - they look up the real user/group name for the user/group id + that is associated with the fake file (see [#678](../../issues/678)) +### New Features +* added some support for the upcoming Python version 3.11 + (see [#677](../../issues/677)) ## [Version 4.5.6](https://pypi.python.org/pypi/pyfakefs/4.5.6) (2022-03-17) Fixes a regression which broke tests with older pytest versions (< 3.9). diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py index 5935c616..e1179a28 100644 --- a/pyfakefs/fake_pathlib.py +++ b/pyfakefs/fake_pathlib.py @@ -754,20 +754,22 @@ class PosixPath(FakePath, PurePosixPath): __slots__ = () def owner(self): - """Return the current user name. It is assumed that the fake - file system was created by the current user. + """Return the username of the file owner. + It is assumed that `st_uid` is related to a real user, + otherwise `KeyError` is raised. """ import pwd - return pwd.getpwuid(os.getuid()).pw_name + return pwd.getpwuid(self.stat().st_uid).pw_name def group(self): - """Return the current group name. It is assumed that the fake - file system was created by the current user. + """Return the group name of the file group. + It is assumed that `st_gid` is related to a real group, + otherwise `KeyError` is raised. """ import grp - return grp.getgrgid(os.getgid()).gr_name + return grp.getgrgid(self.stat().st_gid).gr_name Path = FakePath diff --git a/pyfakefs/tests/fake_pathlib_test.py b/pyfakefs/tests/fake_pathlib_test.py index 0ffe082c..70baef92 100644 --- a/pyfakefs/tests/fake_pathlib_test.py +++ b/pyfakefs/tests/fake_pathlib_test.py @@ -26,6 +26,8 @@ import stat import sys import unittest +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 @@ -1073,12 +1075,37 @@ def test_truncate(self): @unittest.skipIf(sys.platform == 'win32', 'no pwd and grp modules in Windows') def test_owner_and_group_posix(self): - self.check_posix_only() path = self.make_path('some_file') self.create_file(path) self.assertTrue(self.path(path).owner()) self.assertTrue(self.path(path).group()) + @unittest.skipIf(sys.platform == 'win32', + 'no pwd and grp modules in Windows') + def test_changed_owner_and_group(self): + def fake_getpwuid(uid): + if uid == 42: + user_struct = namedtuple('user', 'pw_name, pw_uid') + user_struct.pw_name = 'NewUser' + return user_struct + raise KeyError + + def fake_getgrgid(uid): + if uid == 5: + group_struct = namedtuple('group', 'gr_name, gr_gid') + group_struct.gr_name = 'NewGroup' + return group_struct + raise KeyError + + self.skip_real_fs() + path = self.make_path('some_file') + self.create_file(path) + self.os.chown(path, 42, 5) + with mock.patch('pwd.getpwuid', fake_getpwuid): + with mock.patch('grp.getgrgid', fake_getgrgid): + self.assertEqual('NewUser', self.path(path).owner()) + self.assertEqual('NewGroup', self.path(path).group()) + def test_owner_and_group_windows(self): self.check_windows_only() path = self.make_path('some_file')