mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-37689: add Path.is_relative_to() method (GH-14982)
This commit is contained in:
parent
8a784af750
commit
82642a052d
4 changed files with 111 additions and 1 deletions
|
@ -273,7 +273,7 @@ Methods and properties
|
||||||
|
|
||||||
.. testsetup::
|
.. testsetup::
|
||||||
|
|
||||||
from pathlib import PurePosixPath, PureWindowsPath
|
from pathlib import PurePath, PurePosixPath, PureWindowsPath
|
||||||
|
|
||||||
Pure paths provide the following methods and properties:
|
Pure paths provide the following methods and properties:
|
||||||
|
|
||||||
|
@ -462,6 +462,19 @@ Pure paths provide the following methods and properties:
|
||||||
True
|
True
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: PurePath.is_relative_to(*other)
|
||||||
|
|
||||||
|
Return whether or not this path is relative to the *other* path.
|
||||||
|
|
||||||
|
>>> p = PurePath('/etc/passwd')
|
||||||
|
>>> p.is_relative_to('/etc')
|
||||||
|
True
|
||||||
|
>>> p.is_relative_to('/usr')
|
||||||
|
False
|
||||||
|
|
||||||
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
|
||||||
.. method:: PurePath.is_reserved()
|
.. method:: PurePath.is_reserved()
|
||||||
|
|
||||||
With :class:`PureWindowsPath`, return ``True`` if the path is considered
|
With :class:`PureWindowsPath`, return ``True`` if the path is considered
|
||||||
|
|
|
@ -886,6 +886,15 @@ class PurePath(object):
|
||||||
return self._from_parsed_parts('', root if n == 1 else '',
|
return self._from_parsed_parts('', root if n == 1 else '',
|
||||||
abs_parts[n:])
|
abs_parts[n:])
|
||||||
|
|
||||||
|
def is_relative_to(self, *other):
|
||||||
|
"""Return True if the path is relative to another path or False.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self.relative_to(*other)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parts(self):
|
def parts(self):
|
||||||
"""An object providing sequence-like access to the
|
"""An object providing sequence-like access to the
|
||||||
|
|
|
@ -619,6 +619,40 @@ class _BasePurePathTest(object):
|
||||||
self.assertRaises(ValueError, p.relative_to, '')
|
self.assertRaises(ValueError, p.relative_to, '')
|
||||||
self.assertRaises(ValueError, p.relative_to, P('a'))
|
self.assertRaises(ValueError, p.relative_to, P('a'))
|
||||||
|
|
||||||
|
def test_is_relative_to_common(self):
|
||||||
|
P = self.cls
|
||||||
|
p = P('a/b')
|
||||||
|
self.assertRaises(TypeError, p.is_relative_to)
|
||||||
|
self.assertRaises(TypeError, p.is_relative_to, b'a')
|
||||||
|
self.assertTrue(p.is_relative_to(P()))
|
||||||
|
self.assertTrue(p.is_relative_to(''))
|
||||||
|
self.assertTrue(p.is_relative_to(P('a')))
|
||||||
|
self.assertTrue(p.is_relative_to('a/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('a/b')))
|
||||||
|
self.assertTrue(p.is_relative_to('a/b'))
|
||||||
|
# With several args.
|
||||||
|
self.assertTrue(p.is_relative_to('a', 'b'))
|
||||||
|
# Unrelated paths.
|
||||||
|
self.assertFalse(p.is_relative_to(P('c')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('a/b/c')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('a/c')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/a')))
|
||||||
|
p = P('/a/b')
|
||||||
|
self.assertTrue(p.is_relative_to(P('/')))
|
||||||
|
self.assertTrue(p.is_relative_to('/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('/a')))
|
||||||
|
self.assertTrue(p.is_relative_to('/a'))
|
||||||
|
self.assertTrue(p.is_relative_to('/a/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('/a/b')))
|
||||||
|
self.assertTrue(p.is_relative_to('/a/b'))
|
||||||
|
# Unrelated paths.
|
||||||
|
self.assertFalse(p.is_relative_to(P('/c')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/a/b/c')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/a/c')))
|
||||||
|
self.assertFalse(p.is_relative_to(P()))
|
||||||
|
self.assertFalse(p.is_relative_to(''))
|
||||||
|
self.assertFalse(p.is_relative_to(P('a')))
|
||||||
|
|
||||||
def test_pickling_common(self):
|
def test_pickling_common(self):
|
||||||
P = self.cls
|
P = self.cls
|
||||||
p = P('/a/b')
|
p = P('/a/b')
|
||||||
|
@ -1062,6 +1096,59 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
|
||||||
self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo'))
|
self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo'))
|
||||||
self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo'))
|
self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo'))
|
||||||
|
|
||||||
|
def test_is_relative_to(self):
|
||||||
|
P = self.cls
|
||||||
|
p = P('C:Foo/Bar')
|
||||||
|
self.assertTrue(p.is_relative_to(P('c:')))
|
||||||
|
self.assertTrue(p.is_relative_to('c:'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('c:foO')))
|
||||||
|
self.assertTrue(p.is_relative_to('c:foO'))
|
||||||
|
self.assertTrue(p.is_relative_to('c:foO/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('c:foO/baR')))
|
||||||
|
self.assertTrue(p.is_relative_to('c:foO/baR'))
|
||||||
|
# Unrelated paths.
|
||||||
|
self.assertFalse(p.is_relative_to(P()))
|
||||||
|
self.assertFalse(p.is_relative_to(''))
|
||||||
|
self.assertFalse(p.is_relative_to(P('d:')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:/Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:Foo/Bar/Baz')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:Foo/Baz')))
|
||||||
|
p = P('C:/Foo/Bar')
|
||||||
|
self.assertTrue(p.is_relative_to('c:'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('c:/')))
|
||||||
|
self.assertTrue(p.is_relative_to(P('c:/foO')))
|
||||||
|
self.assertTrue(p.is_relative_to('c:/foO/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('c:/foO/baR')))
|
||||||
|
self.assertTrue(p.is_relative_to('c:/foO/baR'))
|
||||||
|
# Unrelated paths.
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:/Baz')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:/Foo/Bar/Baz')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:/Foo/Baz')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('C:Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('d:')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('d:/')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('/Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('//C/Foo')))
|
||||||
|
# UNC paths.
|
||||||
|
p = P('//Server/Share/Foo/Bar')
|
||||||
|
self.assertTrue(p.is_relative_to(P('//sErver/sHare')))
|
||||||
|
self.assertTrue(p.is_relative_to('//sErver/sHare'))
|
||||||
|
self.assertTrue(p.is_relative_to('//sErver/sHare/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('//sErver/sHare/Foo')))
|
||||||
|
self.assertTrue(p.is_relative_to('//sErver/sHare/Foo'))
|
||||||
|
self.assertTrue(p.is_relative_to('//sErver/sHare/Foo/'))
|
||||||
|
self.assertTrue(p.is_relative_to(P('//sErver/sHare/Foo/Bar')))
|
||||||
|
self.assertTrue(p.is_relative_to('//sErver/sHare/Foo/Bar'))
|
||||||
|
# Unrelated paths.
|
||||||
|
self.assertFalse(p.is_relative_to(P('/Server/Share/Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('c:/Server/Share/Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('//z/Share/Foo')))
|
||||||
|
self.assertFalse(p.is_relative_to(P('//Server/z/Foo')))
|
||||||
|
|
||||||
def test_is_absolute(self):
|
def test_is_absolute(self):
|
||||||
P = self.cls
|
P = self.cls
|
||||||
# Under NT, only paths with both a drive and a root are absolute.
|
# Under NT, only paths with both a drive and a root are absolute.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add :meth:`is_relative_to` in :class:`PurePath` to determine whether or not one path is relative to another.
|
Loading…
Add table
Add a link
Reference in a new issue