Skip to content

Commit

Permalink
Add apply_umask argument to FakeFilesystem.create_dir
Browse files Browse the repository at this point in the history
* allows to ignore the umask
* closes #1038
  • Loading branch information
mrbean-bremen committed Jul 11, 2024
1 parent 64ed360 commit a6617e5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
12 changes: 10 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
# pyfakefs Release Notes
The released versions correspond to PyPI releases.

## Policy for Python version support
* support for new versions is usually added preliminarily during the Python release beta phase,
official support after the final release
* support for EOL versions is removed as soon as the CI (GitHub actions) does no longer provide
these versions (usually several months after the official EOL)

## Planned changes for next major release (6.0.0)
* remove support for patching legacy modules `scandir` and `pathlib2`
* remove support for Python 3.7
* support for patching legacy modules `scandir` and `pathlib2` will be removed
* the default for `FakeFilesystem.shuffle_listdir_results` will change to `True` to reflect
the real filesystem behavior

## Unreleased

### Enhancements
* added preliminary support for Python 3.13 (tested with beta2) (see [#1017](../../issues/1017))
* added `apply_umask` argument to `FakeFilesystem.create_dir` to allow ignoring the umask (see [#1038](../../issues/1038))

### Fixes
* use real open calls for remaining `pathlib` functions so that it works nice with skippedmodules (see [#1012](../../issues/1012))
Expand Down
15 changes: 11 additions & 4 deletions pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2090,7 +2090,10 @@ def make_string_path(self, path: AnyPath) -> AnyStr: # type: ignore[type-var]
return path_str.replace(os_sep, fake_sep) # type: ignore[return-value]

def create_dir(
self, directory_path: AnyPath, perm_bits: int = helpers.PERM_DEF
self,
directory_path: AnyPath,
perm_bits: int = helpers.PERM_DEF,
apply_umask: bool = True,
) -> FakeDirectory:
"""Create `directory_path` and all the parent directories, and return
the created :py:class:`FakeDirectory<pyfakefs.fake_file.FakeDirectory>` object.
Expand All @@ -2100,6 +2103,8 @@ def create_dir(
Args:
directory_path: The full directory path to create.
perm_bits: The permission bits as set by ``chmod``.
apply_umask: If `True` (default), the current umask is applied
to `perm_bits`.
Returns:
The newly created
Expand Down Expand Up @@ -2138,7 +2143,9 @@ def create_dir(
# set the permission after creating the directories
# to allow directory creation inside a read-only directory
for new_dir in new_dirs:
new_dir.st_mode = S_IFDIR | (perm_bits & ~self.umask)
if apply_umask:
perm_bits &= ~self.umask
new_dir.st_mode = S_IFDIR | perm_bits

return current_dir

Expand Down Expand Up @@ -2169,8 +2176,8 @@ def create_file(
the file is considered to be in "large file mode" and trying
to read from or write to the file will result in an exception.
create_missing_dirs: If `True`, auto create missing directories.
apply_umask: `True` if the current umask must be applied
on `st_mode`.
apply_umask: If `True` (default), the current umask is applied
to `st_mode`.
encoding: If `contents` is of type `str`, the encoding used
for serialization.
errors: The error mode used for encoding/decoding errors.
Expand Down
14 changes: 14 additions & 0 deletions pyfakefs/tests/fake_filesystem_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,20 @@ def test_create_directory(self):
self.assertEqual(os.path.basename(path), new_dir.name)
self.assertTrue(stat.S_IFDIR & new_dir.st_mode)

def test_create_dir_umask(self):
old_umask = self.filesystem.umask
self.filesystem.umask = 0o22
path = "foo/bar/baz"
self.filesystem.create_dir(path, perm_bits=0o777)
new_dir = self.filesystem.get_object(path)
self.assertEqual(stat.S_IFDIR | 0o755, new_dir.st_mode)

path = "foo/bar/boo"
self.filesystem.create_dir(path, perm_bits=0o777, apply_umask=False)
new_dir = self.filesystem.get_object(path)
self.assertEqual(stat.S_IFDIR | 0o777, new_dir.st_mode)
self.filesystem.umask = old_umask

def test_create_directory_already_exists_error(self):
path = "foo/bar/baz"
self.filesystem.create_dir(path)
Expand Down

0 comments on commit a6617e5

Please sign in to comment.