Skip to content

Commit d875151

Browse files
authored
Fix pure windows path behavior (#1011)
* Hard-code path separators in `Pure*Path` classes * Fixes #1006
1 parent d11b848 commit d875151

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ The released versions correspond to PyPI releases.
1111
* The usage of the `pathlib2` and `scandir` modules in pyfakefs is now deprecated.
1212
They will now cause deprecation warnings if still used. Support for patching
1313
these modules will be removed in pyfakefs 6.0.
14+
* `PureWindowsPath` and `PurePosixPath` now use filesystem-independent path separators,
15+
and their path-parsing behaviors are now consistent regardless of runtime platform
16+
and/or faked filesystem customization (see [#1006](../../issues/1006)).
1417

1518
## [Version 5.4.1](https://pypi.python.org/pypi/pyfakefs/5.4.0) (2024-04-11)
1619
Fixes a regression.

pyfakefs/fake_pathlib.py

+28-5
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,38 @@ def init_module(filesystem):
5555
# pylint: disable=protected-access
5656
FakePath.filesystem = filesystem
5757
if sys.version_info < (3, 12):
58-
FakePathlibModule.PureWindowsPath._flavour = _FakeWindowsFlavour(filesystem)
59-
FakePathlibModule.PurePosixPath._flavour = _FakePosixFlavour(filesystem)
58+
FakePathlibModule.WindowsPath._flavour = _FakeWindowsFlavour(filesystem)
59+
FakePathlibModule.PosixPath._flavour = _FakePosixFlavour(filesystem)
60+
61+
# Pure POSIX path separators must be filesystem-independent.
62+
fake_pure_posix_flavour = _FakePosixFlavour(filesystem)
63+
fake_pure_posix_flavour.sep = "/"
64+
fake_pure_posix_flavour.altsep = None
65+
FakePathlibModule.PurePosixPath._flavour = fake_pure_posix_flavour
66+
67+
# Pure Windows path separators must be filesystem-independent.
68+
fake_pure_nt_flavour = _FakePosixFlavour(filesystem)
69+
fake_pure_nt_flavour.sep = "\\"
70+
fake_pure_nt_flavour.altsep = "/"
71+
FakePathlibModule.PureWindowsPath._flavour = fake_pure_nt_flavour
6072
else:
6173
# in Python 3.12, the flavour is no longer an own class,
6274
# but points to the os-specific path module (posixpath/ntpath)
6375
fake_os = FakeOsModule(filesystem)
64-
fake_path = fake_os.path
65-
FakePathlibModule.PureWindowsPath._flavour = fake_path
66-
FakePathlibModule.PurePosixPath._flavour = fake_path
76+
FakePathlibModule.PosixPath._flavour = fake_os.path
77+
FakePathlibModule.WindowsPath._flavour = fake_os.path
78+
79+
# Pure POSIX path separators must be filesystem independent.
80+
fake_pure_posix_os = FakeOsModule(filesystem)
81+
fake_pure_posix_os.path.sep = "/"
82+
fake_pure_posix_os.path.altsep = None
83+
FakePathlibModule.PurePosixPath._flavour = fake_pure_posix_os.path
84+
85+
# Pure Windows path separators must be filesystem independent.
86+
fake_pure_nt_os = FakeOsModule(filesystem)
87+
fake_pure_nt_os.path.sep = "\\"
88+
fake_pure_nt_os.path.altsep = "/"
89+
FakePathlibModule.PureWindowsPath._flavour = fake_pure_nt_os.path
6790

6891

6992
def _wrap_strfunc(strfunc):

pyfakefs/tests/fake_pathlib_test.py

+26
Original file line numberDiff line numberDiff line change
@@ -1286,5 +1286,31 @@ def test_is_file_for_unreadable_dir_windows(self):
12861286
path.is_file()
12871287

12881288

1289+
class FakePathlibModulePurePathTest(unittest.TestCase):
1290+
def test_windows_pure_path_parsing(self):
1291+
"""Verify faked pure Windows paths use filesystem-independent separators."""
1292+
1293+
path = r"C:\Windows\cmd.exe"
1294+
self.assertEqual(
1295+
fake_pathlib.FakePathlibModule.PureWindowsPath(path).stem,
1296+
pathlib.PureWindowsPath(path).stem,
1297+
)
1298+
1299+
path = r"C:/Windows/cmd.exe"
1300+
self.assertEqual(
1301+
fake_pathlib.FakePathlibModule.PureWindowsPath(path).stem,
1302+
pathlib.PureWindowsPath(path).stem,
1303+
)
1304+
1305+
def test_posix_pure_path_parsing(self):
1306+
"""Verify faked pure POSIX paths use filesystem-independent separators."""
1307+
1308+
path = r"/bin/bash"
1309+
self.assertEqual(
1310+
fake_pathlib.FakePathlibModule.PurePosixPath(path).stem,
1311+
pathlib.PurePosixPath(path).stem,
1312+
)
1313+
1314+
12891315
if __name__ == "__main__":
12901316
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)