]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-111429: Speed up `pathlib.PurePath.[is_]relative_to()` (#111431)
authorBarney Gale <barney.gale@gmail.com>
Sun, 12 Nov 2023 22:59:17 +0000 (22:59 +0000)
committerGitHub <noreply@github.com>
Sun, 12 Nov 2023 22:59:17 +0000 (22:59 +0000)
Lib/pathlib.py
Misc/NEWS.d/next/Library/2023-10-28-22-11-11.gh-issue-111429.mJGxuQ.rst [new file with mode: 0644]

index e3eecc3b6d73e3efaefa70898ed42b4fde0135c5..47a043c5e6b1b95c9f12fc2e99a0a348dc9ae07f 100644 (file)
@@ -647,9 +647,11 @@ class PurePath:
                    "scheduled for removal in Python {remove}")
             warnings._deprecated("pathlib.PurePath.relative_to(*args)", msg,
                                  remove=(3, 14))
-        other = self.with_segments(other, *_deprecated)
+            other = self.with_segments(other, *_deprecated)
+        elif not isinstance(other, PurePath):
+            other = self.with_segments(other)
         for step, path in enumerate([other] + list(other.parents)):
-            if self.is_relative_to(path):
+            if path == self or path in self.parents:
                 break
             elif not walk_up:
                 raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}")
@@ -658,7 +660,7 @@ class PurePath:
         else:
             raise ValueError(f"{str(self)!r} and {str(other)!r} have different anchors")
         parts = ['..'] * step + self._tail[len(path._tail):]
-        return self.with_segments(*parts)
+        return self._from_parsed_parts('', '', parts)
 
     def is_relative_to(self, other, /, *_deprecated):
         """Return True if the path is relative to another path or False.
@@ -669,7 +671,9 @@ class PurePath:
                    "scheduled for removal in Python {remove}")
             warnings._deprecated("pathlib.PurePath.is_relative_to(*args)",
                                  msg, remove=(3, 14))
-        other = self.with_segments(other, *_deprecated)
+            other = self.with_segments(other, *_deprecated)
+        elif not isinstance(other, PurePath):
+            other = self.with_segments(other)
         return other == self or other in self.parents
 
     @property
diff --git a/Misc/NEWS.d/next/Library/2023-10-28-22-11-11.gh-issue-111429.mJGxuQ.rst b/Misc/NEWS.d/next/Library/2023-10-28-22-11-11.gh-issue-111429.mJGxuQ.rst
new file mode 100644 (file)
index 0000000..c8bc4c5
--- /dev/null
@@ -0,0 +1,2 @@
+Speed up :meth:`pathlib.PurePath.relative_to` and
+:meth:`~pathlib.PurePath.is_relative_to`.