diff --git a/CHANGES.md b/CHANGES.md index 47e99662..6d1f1658 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,8 +4,11 @@ The release versions are PyPi releases. ## Version 3.2 (as yet unreleased) #### New Features - * Added possibility to add lazily read real files to fake filesystem - * Added the CHANGES.md release notes to the release manifest + * Added new methods to `fake_filesystem.FakeFilesystem` that make real files + and directories appear within the fake file system: + `AddRealFile()`, `AddRealDirectory()` and `AddRealPaths()`. + File contents are read from the real file system only when needed. + * Added the CHANGES.md release notes to the release manifest #### Fixes * `pathlib.glob()` incorrectly handled case under MacOS (#167) diff --git a/example.py b/example.py index 6c956a6f..3bce909a 100644 --- a/example.py +++ b/example.py @@ -132,5 +132,10 @@ def rm_tree(path): shutil.rmtree(path) def scandir(path): - """Returns a list of directory entries for the given path.""" + """Return a list of directory entries for the given path.""" return list(os.scandir(path)) + +def file_contents(path): + """Return the contents of the given path as byte array.""" + with open(path, 'rb') as f: + return f.read() diff --git a/example_test.py b/example_test.py index 4d3f7782..7995000a 100644 --- a/example_test.py +++ b/example_test.py @@ -30,6 +30,8 @@ import os import sys +from pyfakefs.fake_filesystem_unittest import REAL_OPEN + if sys.version_info < (2, 7): import unittest2 as unittest else: @@ -135,13 +137,22 @@ def test_scandir(self): self.fs.CreateFile('/linktest/linked') self.fs.CreateLink('/test/linked_file', '/linktest/linked') - entries = sorted(os.scandir('/test'), key=lambda e: e.name) + entries = sorted(example.scandir('/test'), key=lambda e: e.name) self.assertEqual(3, len(entries)) self.assertEqual('linked_file', entries[1].name) self.assertTrue(entries[0].is_dir()) self.assertTrue(entries[1].is_symlink()) self.assertTrue(entries[2].is_file()) + def test_real_file_access(self): + """Test `example.file_contents()` for a real file after adding it using `AddRealFile()`.""" + real_file = __file__ + with REAL_OPEN(real_file, 'rb') as f: + real_contents = f.read() + self.assertRaises(IOError, example.file_contents, real_file) + self.fs.AddRealFile(real_file) + self.assertEqual(example.file_contents(real_file), real_contents) + if __name__ == "__main__": unittest.main() diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 318e7794..d0fdd6c3 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -196,7 +196,7 @@ def __init__(self, name, st_mode=stat.S_IFREG | PERM_DEF_FILE, self.name = name self.st_mode = st_mode self._byte_contents = self._EncodeContents(contents, encoding) - self.st_size = len(self._byte_contents) if self._byte_contents else 0 + self.st_size = len(self._byte_contents) if self._byte_contents is not None else 0 self.filesystem = filesystem self.epoch = 0 self._st_ctime = time.time() # times are accessed through properties @@ -834,7 +834,7 @@ def GetOpenFile(self, file_des): if not isinstance(file_des, int): raise TypeError('an integer is required') if (file_des >= len(self.open_files) or - self.open_files[file_des] is None): + self.open_files[file_des] is None): raise OSError(errno.EBADF, 'Bad file descriptor', file_des) return self.open_files[file_des] @@ -897,7 +897,7 @@ def CollapsePath(self, path): continue if component == '..': if collapsed_path_components and ( - collapsed_path_components[-1] != '..'): + collapsed_path_components[-1] != '..'): # Remove an up-reference: directory/.. collapsed_path_components.pop() continue @@ -929,7 +929,7 @@ def NormalizeCase(self, path): for component in path_components: dir_name, current_dir = self._DirectoryContent(current_dir, component) if current_dir is None or ( - current_dir._byte_contents is None and current_dir.st_size == 0): + current_dir._byte_contents is None and current_dir.st_size == 0): return path normalized_components.append(dir_name) normalized_path = self.path_separator.join(normalized_components) @@ -1014,7 +1014,7 @@ def SplitDrive(self, path): # UNC path handling is here since Python 2.7.8, back-ported from Python 3 if sys.version_info >= (2, 7, 8): if (path[0:2] == self.path_separator * 2) and ( - path[2:3] != self.path_separator): + path[2:3] != self.path_separator): # UNC path handling - splits off the mount point instead of the drive sep_index = path.find(self.path_separator, 2) if sep_index == -1: