summaryrefslogtreecommitdiffstats
path: root/Lib/pathlib/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/pathlib/__init__.py')
-rw-r--r--Lib/pathlib/__init__.py22
1 files changed, 17 insertions, 5 deletions
diff --git a/Lib/pathlib/__init__.py b/Lib/pathlib/__init__.py
index 26e14b3..ccdd9c3 100644
--- a/Lib/pathlib/__init__.py
+++ b/Lib/pathlib/__init__.py
@@ -11,6 +11,7 @@ import os
import posixpath
import sys
import warnings
+from itertools import chain
from _collections_abc import Sequence
try:
@@ -254,10 +255,19 @@ class PurePath(_abc.PurePathBase):
"scheduled for removal in Python 3.14")
warnings.warn(msg, DeprecationWarning, stacklevel=2)
other = self.with_segments(other, *_deprecated)
- path = _abc.PurePathBase.relative_to(self, other, walk_up=walk_up)
- path._drv = path._root = ''
- path._tail_cached = path._raw_paths.copy()
- return path
+ elif not isinstance(other, PurePath):
+ other = self.with_segments(other)
+ for step, path in enumerate(chain([other], other.parents)):
+ 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}")
+ elif path.name == '..':
+ raise ValueError(f"'..' segment in {str(other)!r} cannot be walked")
+ else:
+ raise ValueError(f"{str(self)!r} and {str(other)!r} have different anchors")
+ parts = ['..'] * step + self._tail[len(path._tail):]
+ 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.
@@ -268,7 +278,9 @@ class PurePath(_abc.PurePathBase):
"scheduled for removal in Python 3.14")
warnings.warn(msg, DeprecationWarning, stacklevel=2)
other = self.with_segments(other, *_deprecated)
- return _abc.PurePathBase.is_relative_to(self, other)
+ elif not isinstance(other, PurePath):
+ other = self.with_segments(other)
+ return other == self or other in self.parents
def as_uri(self):
"""Return the path as a URI."""