Skip to content

Commit

Permalink
Added support for path-like object argument in convenience methods
Browse files Browse the repository at this point in the history
- concerns create_file(), create_dir(), create_symlink(), add_real_file() and add_real_directory()
- closes #409
  • Loading branch information
mrbean-bremen committed Jun 2, 2018
1 parent 297e362 commit f9ff1c6
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ The release versions are PyPi releases.
## Version 3.5 (As yet unreleased)

#### New Features

* added support for path-like objects as arguments in `create_file()`,
`create_dir()`, `create_symlink()`, `add_real_file()` and
`add_real_directory()` (Python >= 3.6, see [#409](../../issues/409))

#### Infrastructure
* moved tests into package
* use README.md in pypi ([#358](../../issues/358))
Expand Down
12 changes: 12 additions & 0 deletions pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2176,6 +2176,12 @@ def remove_object(self, file_path):
except AttributeError:
self.raise_io_error(errno.ENOTDIR, file_path)

def make_string_path(self, path):
path = make_string_path(path)
os_sep = self._matching_string(path, os.sep)
fake_sep = self._matching_string(path, self.path_separator)
return path.replace(os_sep, fake_sep)

def create_dir(self, directory_path, perm_bits=PERM_DEF):
"""Create `directory_path`, and all the parent directories.
Expand All @@ -2191,6 +2197,7 @@ def create_dir(self, directory_path, perm_bits=PERM_DEF):
Raises:
OSError: if the directory already exists.
"""
directory_path = self.make_string_path(directory_path)
directory_path = self.absnormpath(directory_path)
self._auto_mount_drive_if_needed(directory_path)
if self.exists(directory_path, check_link=True):
Expand Down Expand Up @@ -2279,6 +2286,8 @@ def add_real_file(self, source_path, read_only=True, target_path=None):
that `pyfakefs` must not modify the real file system.
"""
target_path = target_path or source_path
source_path = make_string_path(source_path)
target_path = self.make_string_path(target_path)
real_stat = os.stat(source_path)
fake_file = self.create_file_internally(target_path,
read_from_real_fs=True)
Expand Down Expand Up @@ -2398,6 +2407,7 @@ def create_file_internally(self, file_path,
raw_io: `True` if called from low-level API (`os.open`)
"""
error_class = OSError if raw_io else IOError
file_path = self.make_string_path(file_path)
file_path = self.absnormpath(file_path)
if not is_int_type(st_mode):
raise TypeError(
Expand Down Expand Up @@ -2464,6 +2474,8 @@ def create_symlink(self, file_path, link_target, create_missing_dirs=True):
"on Windows before Python 3.2")

# the link path cannot end with a path separator
file_path = self.make_string_path(file_path)
link_target = self.make_string_path(link_target)
file_path = self.normcase(file_path)
if self.ends_with_path_separator(file_path):
if self.exists(file_path):
Expand Down
58 changes: 57 additions & 1 deletion pyfakefs/tests/fake_pathlib_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import sys
import unittest

from pyfakefs import fake_pathlib
from pyfakefs import fake_pathlib, fake_filesystem
from pyfakefs.tests.test_utils import RealFsTestCase

is_windows = sys.platform == 'win32'
Expand Down Expand Up @@ -910,5 +910,61 @@ def use_real_fs(self):
return True


@unittest.skipIf(sys.version_info < (3, 6),
'Path-like objects new in Python 3.6')
class FakeFilesystemPathLikeObjectTest(unittest.TestCase):

def setUp(self):
self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
self.pathlib = fake_pathlib.FakePathlibModule(self.filesystem)
self.os = fake_filesystem.FakeOsModule(self.filesystem)

def test_create_dir_with_pathlib_path(self):
dir_path_string = 'foo/bar/baz'
dir_path = self.pathlib.Path(dir_path_string)
self.filesystem.create_dir(dir_path)
self.assertTrue(self.os.path.exists(dir_path_string))
self.assertEqual(stat.S_IFDIR,
self.os.stat(dir_path_string).st_mode & stat.S_IFDIR)

def test_create_file_with_pathlib_path(self):
file_path_string = 'foo/bar/baz'
file_path = self.pathlib.Path(file_path_string)
self.filesystem.create_file(file_path)
self.assertTrue(self.os.path.exists(file_path_string))
self.assertEqual(stat.S_IFREG,
self.os.stat(file_path_string).st_mode & stat.S_IFREG)

def test_create_symlink_with_pathlib_path(self):
file_path = self.pathlib.Path('foo/bar/baz')
link_path_string = 'foo/link'
link_path = self.pathlib.Path(link_path_string)
self.filesystem.create_symlink(link_path, file_path)
self.assertTrue(self.os.path.lexists(link_path_string))
self.assertEqual(stat.S_IFLNK,
self.os.lstat(link_path_string).st_mode &
stat.S_IFLNK)

def test_add_existing_real_file_with_pathlib_path(self):
real_file_path_string = os.path.abspath(__file__)
real_file_path = self.pathlib.Path(real_file_path_string)
self.filesystem.add_real_file(real_file_path)
fake_filepath_string = real_file_path_string.replace(
os.sep, self.os.sep)
self.assertTrue(self.os.path.exists(fake_filepath_string))
self.assertEqual(stat.S_IFREG, self.os.stat(
fake_filepath_string).st_mode & stat.S_IFREG)

def test_add_existing_real_directory_with_pathlib_path(self):
real_dirpath_string = os.path.dirname(os.path.abspath(__file__))
real_dir_path = self.pathlib.Path(real_dirpath_string)
self.filesystem.add_real_directory(real_dir_path)
fake_dirpath_string = real_dirpath_string.replace(
os.sep, self.os.sep)
self.assertTrue(self.os.path.exists(fake_dirpath_string))
self.assertEqual(stat.S_IFDIR, self.os.stat(
fake_dirpath_string).st_mode & stat.S_IFDIR)


if __name__ == '__main__':
unittest.main()

0 comments on commit f9ff1c6

Please sign in to comment.