Permalink
Browse files

Set st_uid and st_gid for new files to current user/group ID

- allow to set current group ID
- see #449
  • Loading branch information...
mrbean-bremen committed Nov 8, 2018
1 parent 6fa71cf commit 8067e5664577a74a705c7ae9d2a7f3d1278bbaaf
View
@@ -4,6 +4,8 @@ The release versions are PyPi releases.
## Version 3.6 (as yet unreleased)
#### New Features
* allow to set current group ID, set current user ID and group ID as
`st_uid` and `st_gid` in new files ([#449](../../issues/449))
#### Fixes
* fixed using `modules_to_patch` with modules without `dir()`
View
@@ -7,7 +7,7 @@ Public Modules and Classes
Fake filesystem module
----------------------
.. automodule:: pyfakefs.fake_filesystem
:members: set_uid
:members: set_uid, set_gid
Fake filesystem classes
-----------------------
@@ -161,12 +161,13 @@
)
NR_STD_STREAMS = 3
USER_ID = None
USER_ID = 1
GROUP_ID = 1
def set_uid(uid):
"""Set the global user id. Currently only used to differentiate between
a normal user and the root user (uid 0).
"""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).
For the root user, some permission restrictions are ignored.
Args:
@@ -176,6 +177,17 @@ def set_uid(uid):
USER_ID = uid
def set_gid(gid):
"""Set the global group id. This is only used to set st_gid for new files,
no permision checks are performed.
Args:
gid: (int) the group ID of the user calling the file system functions.
"""
global GROUP_ID
GROUP_ID = gid
def is_root():
"""Return True if the current user is the root user."""
return USER_ID == 0
@@ -214,9 +226,10 @@ class FakeFile(object):
* `st_ino`: the inode number - a unique number identifying the file
* `st_dev`: a unique number identifying the (fake) file system device
the file belongs to
Other attributes needed by `os.stat` are assigned a default value of
`None`. These include `st_uid` and `st_gid`.
* `st_uid`: always set to USER_ID, which can be changed globally using
`set_uid`
* `st_gid`: always set to GROUP_ID, which can be changed globally using
`set_gid`
.. note:: The resolution for `st_ctime`, `st_mtime` and `st_atime` in the
real file system depends on the used file system (for example it is
@@ -259,7 +272,7 @@ def __init__(self, name, st_mode=S_IFREG | PERM_DEF_FILE,
self._side_effect = side_effect
self.name = name
self.stat_result = FakeStatResult(
filesystem.is_windows_fs, time.time())
filesystem.is_windows_fs, USER_ID, GROUP_ID, time.time())
self.stat_result.st_mode = st_mode
self.encoding = encoding
self.errors = errors or 'strict'
View
@@ -70,14 +70,14 @@ class FakeStatResult(object):
long_type = int # Python 3
_stat_float_times = sys.version_info >= (2, 5)
def __init__(self, is_windows, initial_time=None):
def __init__(self, is_windows, user_id, group_id, initial_time=None):
self._use_float = None
self.st_mode = None
self.st_ino = None
self.st_dev = None
self.st_nlink = 0
self.st_uid = None
self.st_gid = None
self.st_uid = user_id
self.st_gid = group_id
self._st_size = None
self.is_windows = is_windows
if initial_time is not None:
@@ -357,7 +357,7 @@ def use_real_fs(self):
class FakeCopyFileTest(RealFsTestCase):
def tearDown(self):
set_uid(None)
set_uid(1)
super(FakeCopyFileTest, self).tearDown()
def test_common_case(self):
@@ -24,7 +24,7 @@
import unittest
from pyfakefs import fake_filesystem
from pyfakefs.fake_filesystem import set_uid
from pyfakefs.fake_filesystem import set_uid, set_gid
from pyfakefs.tests.test_utils import DummyTime, TestCase
@@ -260,7 +260,7 @@ def setUp(self):
'foobaz', filesystem=self.filesystem)
self.fake_grandchild = fake_filesystem.FakeDirectory(
'quux', filesystem=self.filesystem)
set_uid(None)
set_uid(1)
def test_new_filesystem(self):
self.assertEqual('/', self.filesystem.path_separator)
@@ -545,9 +545,22 @@ def test_create_file(self):
self.assertTrue(self.filesystem.exists(os.path.dirname(path)))
new_file = self.filesystem.get_object(path)
self.assertEqual(os.path.basename(path), new_file.name)
self.assertTrue(stat.S_IFREG & new_file.st_mode)
self.assertEqual(1, new_file.st_uid)
self.assertEqual(1, new_file.st_gid)
self.assertEqual(new_file, retval)
def test_create_file_with_changed_ids(self):
path = 'foo/bar/baz'
set_uid(42)
set_gid(2)
retval = self.filesystem.create_file(path)
self.assertTrue(self.filesystem.exists(path))
new_file = self.filesystem.get_object(path)
self.assertEqual(42, new_file.st_uid)
self.assertEqual(2, new_file.st_gid)
set_uid(1)
set_gid(1)
def test_empty_file_created_for_none_contents(self):
fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
path = 'foo/bar/baz'
@@ -1816,7 +1829,7 @@ def setUp(self):
self.pyfakefs_path = os.path.split(
os.path.dirname(os.path.abspath(__file__)))[0]
self.root_path = os.path.split(self.pyfakefs_path)[0]
set_uid(None)
set_uid(1)
def test_add_non_existing_real_file_raises(self):
nonexisting_path = os.path.join('nonexisting', 'test.txt')
@@ -40,7 +40,7 @@ class FakeFileOpenTest(FakeFileOpenTestBase):
def setUp(self):
super(FakeFileOpenTest, self).setUp()
self.orig_time = time.time
set_uid(None)
set_uid(1)
def tearDown(self):
super(FakeFileOpenTest, self).tearDown()
@@ -54,7 +54,7 @@ def setUp(self):
super(FakeOsModuleTest, self).setUp()
self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK
self.rw = self.os.R_OK | self.os.W_OK
set_uid(None)
set_uid(1)
def test_chdir(self):
"""chdir should work on a directory."""
@@ -1680,7 +1680,7 @@ def test_makedirs_raises_if_access_denied(self):
self.os.chmod(directory, 0o400)
directory = self.make_path('a', 'b')
set_uid(None)
set_uid(1)
self.assertRaises(Exception, self.os.makedirs, directory)
if not self.use_real_fs():
set_uid(0)
@@ -2683,7 +2683,7 @@ def test_fdopen_mode(self):
self.os.fdopen(fileno1)
self.os.fdopen(fileno1, 'r')
exception = OSError if self.is_python2 else IOError
set_uid(None)
set_uid(1)
self.assertRaises(exception, self.os.fdopen, fileno1, 'w')
set_uid(0)
self.os.fdopen(fileno1, 'w')

0 comments on commit 8067e56

Please sign in to comment.