Skip to content

Commit

Permalink
pythongh-105002: [pathlib] Fix relative_to with walk_up=True using ".."
Browse files Browse the repository at this point in the history
It makes sense to raise an Error because ".." can not
be resolved and the current working directory is unknown.
  • Loading branch information
kukovecz committed Jul 24, 2023
1 parent 0ba07b2 commit 0eb590e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 2 deletions.
6 changes: 4 additions & 2 deletions Lib/pathlib.py
Expand Up @@ -633,10 +633,12 @@ def relative_to(self, other, /, *_deprecated, walk_up=False):
for step, path in enumerate([other] + list(other.parents)):
if self.is_relative_to(path):
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")
if step and not walk_up:
raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}")
parts = ['..'] * step + self._tail[len(path._tail):]
return self.with_segments(*parts)

Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_pathlib.py
Expand Up @@ -693,8 +693,14 @@ def test_relative_to_common(self):
self.assertRaises(ValueError, p.relative_to, P('a/b/c'))
self.assertRaises(ValueError, p.relative_to, P('a/c'))
self.assertRaises(ValueError, p.relative_to, P('/a'))
self.assertRaises(ValueError, p.relative_to, P("../a"))
self.assertRaises(ValueError, p.relative_to, P("a/.."))
self.assertRaises(ValueError, p.relative_to, P("/a/.."))
self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P('/a'), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True)
p = P('/a/b')
self.assertEqual(p.relative_to(P('/')), P('a/b'))
self.assertEqual(p.relative_to('/'), P('a/b'))
Expand Down Expand Up @@ -723,8 +729,14 @@ def test_relative_to_common(self):
self.assertRaises(ValueError, p.relative_to, P())
self.assertRaises(ValueError, p.relative_to, '')
self.assertRaises(ValueError, p.relative_to, P('a'))
self.assertRaises(ValueError, p.relative_to, P("../a"))
self.assertRaises(ValueError, p.relative_to, P("a/.."))
self.assertRaises(ValueError, p.relative_to, P("/a/.."))
self.assertRaises(ValueError, p.relative_to, P(''), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P('a'), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True)
self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True)

def test_is_relative_to_common(self):
P = self.cls
Expand Down
@@ -0,0 +1 @@
Fix PurePath.relative_to function with walk_up=True parameter when other path contains `..` component(s)

0 comments on commit 0eb590e

Please sign in to comment.