Skip to content

Commit

Permalink
Allow fake pathlib to be used in other os
Browse files Browse the repository at this point in the history
- adapted fake pathlib.home() to work in other os
- fixes #558
  • Loading branch information
mrbean-bremen committed Oct 15, 2020
1 parent 4fe9dc7 commit 67b65ef
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 26 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The released versions correspond to PyPi releases.
(see [#554](../../issues/554))

#### Fixes
* fix handling of real files in combination with `home` if simulating
Posix under Windows (see [#558](../../issues/558))
* do not call fake `open` if called from skipped module
(see [#552](../../issues/552))
* do not call fake `pathlib.Path` if called from skipped module
Expand Down
5 changes: 4 additions & 1 deletion pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,10 @@ def _starts_with_drive_letter(self, file_path):
the path starts with a drive letter.
"""
colon = matching_string(file_path, ':')
return (self.is_windows_fs and len(file_path) >= 2 and
# we also allow a drive letter if only the real fs is Windows
# to allow for real path names
return ((self.is_windows_fs or os.name == 'nt') and
len(file_path) >= 2 and
file_path[:1].isalpha and (file_path[1:2]) == colon)

def _starts_with_root_path(self, file_path):
Expand Down
37 changes: 22 additions & 15 deletions pyfakefs/fake_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,8 @@ class FakePath(pathlib.Path):
def __new__(cls, *args, **kwargs):
"""Creates the correct subclass based on OS."""
if cls is FakePathlibModule.Path:
cls = (FakePathlibModule.WindowsPath if os.name == 'nt'
cls = (FakePathlibModule.WindowsPath
if cls.filesystem.is_windows_fs
else FakePathlibModule.PosixPath)
self = cls._from_parts(args, init=True)
return self
Expand Down Expand Up @@ -574,8 +575,15 @@ def home(cls):
"""Return a new path pointing to the user's home directory (as
returned by os.path.expanduser('~')).
"""
return cls(cls()._flavour.gethomedir(None).
replace(os.sep, cls.filesystem.path_separator))
home = os.path.expanduser("~")
if cls.filesystem.is_windows_fs != (os.name == 'nt'):
username = os.path.split(home)[1]
if cls.filesystem.is_windows_fs:
home = os.path.join('C:', 'Users', username)
else:
home = os.path.join('home', username)
cls.filesystem.create_dir(home)
return cls(home.replace(os.sep, cls.filesystem.path_separator))

def samefile(self, other_path):
"""Return whether other_path is the same or not as this file
Expand Down Expand Up @@ -660,18 +668,17 @@ class PureWindowsPath(PurePath):
"""A subclass of PurePath, that represents Windows filesystem paths"""
__slots__ = ()

if sys.platform == 'win32':
class WindowsPath(FakePath, PureWindowsPath):
"""A subclass of Path and PureWindowsPath that represents
concrete Windows filesystem paths.
"""
__slots__ = ()
else:
class PosixPath(FakePath, PurePosixPath):
"""A subclass of Path and PurePosixPath that represents
concrete non-Windows filesystem paths.
"""
__slots__ = ()
class WindowsPath(FakePath, PureWindowsPath):
"""A subclass of Path and PureWindowsPath that represents
concrete Windows filesystem paths.
"""
__slots__ = ()

class PosixPath(FakePath, PurePosixPath):
"""A subclass of Path and PurePosixPath that represents
concrete non-Windows filesystem paths.
"""
__slots__ = ()

Path = FakePath

Expand Down
20 changes: 20 additions & 0 deletions pyfakefs/tests/fake_filesystem_unittest_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import unittest
import warnings
from distutils.dir_util import copy_tree, remove_tree
from pathlib import Path
from unittest import TestCase

import pyfakefs.tests.import_as_example
Expand Down Expand Up @@ -743,5 +744,24 @@ def test_run_module(self):
load_configs([self.config_module])


class TestOtherFS(fake_filesystem_unittest.TestCase):
def setUp(self):
self.setUpPyfakefs()
self.fs.is_windows_fs = os.name != 'nt'

def test_real_file_with_home(self):
"""Regression test for #558"""
self.fs.add_real_file(__file__)
with open(__file__) as f:
self.assertTrue(f.read())
home = Path.home()
if sys.version_info < (3, 6):
# fspath support since Python 3.6
home = str(home)
os.chdir(home)
with open(__file__) as f:
self.assertTrue(f.read())


if __name__ == "__main__":
unittest.main()
26 changes: 16 additions & 10 deletions pyfakefs/tests/fake_pathlib_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,21 @@ def test_initialization_type(self):
self.assertTrue(isinstance(path, self.pathlib.WindowsPath))
self.assertTrue(isinstance(path, self.pathlib.PureWindowsPath))
self.assertTrue(self.pathlib.PurePosixPath())
with self.assertRaises(NotImplementedError):
self.pathlib.PosixPath()
# in fake fs, we allow to use the other OS implementation
if self.use_real_fs():
with self.assertRaises(NotImplementedError):
self.pathlib.PosixPath()
else:
self.assertTrue(self.pathlib.PosixPath())
else:
self.assertTrue(isinstance(path, self.pathlib.PosixPath))
self.assertTrue(isinstance(path, self.pathlib.PurePosixPath))
self.assertTrue(self.pathlib.PureWindowsPath())
with self.assertRaises(NotImplementedError):
self.pathlib.WindowsPath()
if self.use_real_fs():
with self.assertRaises(NotImplementedError):
self.pathlib.WindowsPath()
else:
self.assertTrue(self.pathlib.WindowsPath())

def test_init_with_segments(self):
"""Basic initialization tests - taken from pathlib.Path documentation
Expand Down Expand Up @@ -477,13 +484,12 @@ def test_expanduser(self):

def test_home(self):
if is_windows:
self.assertEqual(self.path.home(),
self.path(
os.environ['USERPROFILE'].replace('\\',
'/')))
self.assertEqual(self.path(
os.environ['USERPROFILE'].replace('\\', '/')),
self.path.home())
else:
self.assertEqual(self.path.home(),
self.path(os.environ['HOME']))
self.assertEqual(self.path(os.environ['HOME']),
self.path.home())


class RealPathlibFileObjectPropertyTest(FakePathlibFileObjectPropertyTest):
Expand Down

0 comments on commit 67b65ef

Please sign in to comment.