Allow fake pathlib to be used in other os
- adapted fake pathlib.home() to work in other os
- fixes #558
diff --git a/CHANGES.md b/CHANGES.md
index 508c714..67d8ab1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,6 +11,8 @@
(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
diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py
index 6028696..a0e5e54 100644
--- a/pyfakefs/fake_filesystem.py
+++ b/pyfakefs/fake_filesystem.py
@@ -1668,7 +1668,10 @@
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):
diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py
index 1c726db..ad4ec9c 100644
--- a/pyfakefs/fake_pathlib.py
+++ b/pyfakefs/fake_pathlib.py
@@ -449,7 +449,8 @@
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
@@ -574,8 +575,15 @@
"""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
@@ -660,18 +668,17 @@
"""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
diff --git a/pyfakefs/tests/fake_filesystem_unittest_test.py b/pyfakefs/tests/fake_filesystem_unittest_test.py
index a7b52a8..a4a92e2 100644
--- a/pyfakefs/tests/fake_filesystem_unittest_test.py
+++ b/pyfakefs/tests/fake_filesystem_unittest_test.py
@@ -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
@@ -743,5 +744,24 @@
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()
diff --git a/pyfakefs/tests/fake_pathlib_test.py b/pyfakefs/tests/fake_pathlib_test.py
index 705a3b8..0d96ca7 100644
--- a/pyfakefs/tests/fake_pathlib_test.py
+++ b/pyfakefs/tests/fake_pathlib_test.py
@@ -66,14 +66,21 @@
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
@@ -477,13 +484,12 @@
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):