From 68c0a423673f8b702af035e3c371d095baf102b6 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Mon, 7 Oct 2024 21:26:16 +0200 Subject: [PATCH] Fix PurePosixPath.joinpath under Windows - fixes #1070 --- CHANGES.md | 2 ++ pyfakefs/fake_filesystem.py | 17 ++++++++--------- pyfakefs/tests/fake_pathlib_test.py | 11 ++++------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4655ea09..14ab453b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,6 +29,8 @@ The released versions correspond to PyPI releases. (see [#1053](../../issues/1053)) * `PurePosixPath` reported Windows reserved names as reserved in Python >= 3.12 (see [#1067](../../issues/1067)) +* `PurePosixPath.joinpath()` incorrectly handled paths with drives under Windows in Python >= 3.12 + (see [#1070](../../issues/1070)) ## [Version 5.6.0](https://pypi.python.org/pypi/pyfakefs/5.6.0) (2024-07-12) Adds preliminary Python 3.13 support. diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 79839a1d..1f8f536e 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -1306,18 +1306,17 @@ def joinpaths(self, *paths: AnyStr) -> AnyStr: return paths[0] if self.is_windows_fs: return self._join_paths_with_drive_support(*file_paths) - joined_path_segments = [] + path = file_paths[0] sep = self.get_path_separator(file_paths[0]) - for path_segment in file_paths: - if self._starts_with_root_path(path_segment): + for path_segment in file_paths[1:]: + if path_segment.startswith(sep) or not path: # An absolute path - joined_path_segments = [path_segment] + path = path_segment + elif path.endswith(sep): + path += path_segment else: - if joined_path_segments and not joined_path_segments[-1].endswith(sep): - joined_path_segments.append(sep) - if path_segment: - joined_path_segments.append(path_segment) - return matching_string(file_paths[0], "").join(joined_path_segments) + path += sep + path_segment + return path @overload def _path_components(self, path: str) -> List[str]: ... diff --git a/pyfakefs/tests/fake_pathlib_test.py b/pyfakefs/tests/fake_pathlib_test.py index 0a867fc6..cb15f9b8 100644 --- a/pyfakefs/tests/fake_pathlib_test.py +++ b/pyfakefs/tests/fake_pathlib_test.py @@ -328,13 +328,10 @@ def test_joinpath(self): self.assertEqual( self.path("/foo").joinpath("bar", "baz"), self.path("/foo/bar/baz") ) - if os.name != "nt": - # under Windows, this does not work correctly at the moment - # we get "C:/Program Files" instead - self.assertEqual( - self.path("c:").joinpath("/Program Files"), - self.path("/Program Files"), - ) + self.assertEqual( + self.path("c:").joinpath("/Program Files"), + self.path("/Program Files"), + ) def test_match(self): self.assertTrue(self.path("a/b.py").match("*.py"))