diff --git a/CHANGES.md b/CHANGES.md index 8df7f03a..79ed4ba4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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)) diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 98c754e1..04218593 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -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` object. @@ -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 @@ -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 @@ -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. diff --git a/pyfakefs/tests/fake_filesystem_test.py b/pyfakefs/tests/fake_filesystem_test.py index 7c9e1a56..12c05b8f 100644 --- a/pyfakefs/tests/fake_filesystem_test.py +++ b/pyfakefs/tests/fake_filesystem_test.py @@ -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)