]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-78707: deprecate passing >1 argument to `PurePath.[is_]relative_to()` (GH-94469)
authorBarney Gale <barney.gale@gmail.com>
Sat, 17 Dec 2022 00:14:27 +0000 (00:14 +0000)
committerGitHub <noreply@github.com>
Sat, 17 Dec 2022 00:14:27 +0000 (16:14 -0800)
This brings `relative_to()` and `is_relative_to()` more in line with other pathlib methods like `rename()` and `symlink_to()`.

Resolves #78707.

Doc/library/pathlib.rst
Lib/pathlib.py
Lib/test/test_pathlib.py
Misc/NEWS.d/next/Library/2022-07-01-00-01-22.gh-issue-78707.fHGSuM.rst [new file with mode: 0644]

index 6537637f33c70e82842c4aeb11414b1305bb99fe..47687400c14e3a123ed1e99f181db5ef2e322d84 100644 (file)
@@ -490,7 +490,7 @@ Pure paths provide the following methods and properties:
       True
 
 
-.. method:: PurePath.is_relative_to(*other)
+.. method:: PurePath.is_relative_to(other)
 
    Return whether or not this path is relative to the *other* path.
 
@@ -502,6 +502,10 @@ Pure paths provide the following methods and properties:
 
    .. versionadded:: 3.9
 
+   .. deprecated-removed:: 3.12 3.14
+
+      Passing additional arguments is deprecated; if supplied, they are joined
+      with *other*.
 
 .. method:: PurePath.is_reserved()
 
@@ -564,7 +568,7 @@ Pure paths provide the following methods and properties:
       True
 
 
-.. method:: PurePath.relative_to(*other, walk_up=False)
+.. method:: PurePath.relative_to(other, walk_up=False)
 
    Compute a version of this path relative to the path represented by
    *other*.  If it's impossible, :exc:`ValueError` is raised::
@@ -581,7 +585,7 @@ Pure paths provide the following methods and properties:
           raise ValueError(error_message.format(str(self), str(formatted)))
       ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute.
 
-When *walk_up* is False (the default), the path must start with *other*.
+   When *walk_up* is False (the default), the path must start with *other*.
    When the argument is True, ``..`` entries may be added to form the
    relative path. In all other cases, such as the paths referencing
    different drives, :exc:`ValueError` is raised.::
@@ -605,6 +609,10 @@ When *walk_up* is False (the default), the path must start with *other*.
    .. versionadded:: 3.12
       The *walk_up* argument (old behavior is the same as ``walk_up=False``).
 
+   .. deprecated-removed:: 3.12 3.14
+
+      Passing additional positional arguments is deprecated; if supplied,
+      they are joined with *other*.
 
 .. method:: PurePath.with_name(name)
 
index f31eb3010368d5ec48a2b8d606d16cf5ee2dfe5c..7890fdade4205630752cb7d051f43dd0ea8bd982 100644 (file)
@@ -624,7 +624,7 @@ class PurePath(object):
         return self._from_parsed_parts(self._drv, self._root,
                                        self._parts[:-1] + [name])
 
-    def relative_to(self, *other, walk_up=False):
+    def relative_to(self, other, /, *_deprecated, walk_up=False):
         """Return the relative path to another path identified by the passed
         arguments.  If the operation is not possible (because this is not
         related to the other path), raise ValueError.
@@ -632,10 +632,14 @@ class PurePath(object):
         The *walk_up* parameter controls whether `..` may be used to resolve
         the path.
         """
-        if not other:
-            raise TypeError("need at least one argument")
+        if _deprecated:
+            msg = ("support for supplying more than one positional argument "
+                   "to pathlib.PurePath.relative_to() is deprecated and "
+                   "scheduled for removal in Python {remove}")
+            warnings._deprecated("pathlib.PurePath.relative_to(*args)", msg,
+                                 remove=(3, 14))
         path_cls = type(self)
-        other = path_cls(*other)
+        other = path_cls(other, *_deprecated)
         for step, path in enumerate([other] + list(other.parents)):
             if self.is_relative_to(path):
                 break
@@ -646,12 +650,16 @@ class PurePath(object):
         parts = ('..',) * step + self.parts[len(path.parts):]
         return path_cls(*parts)
 
-    def is_relative_to(self, *other):
+    def is_relative_to(self, other, /, *_deprecated):
         """Return True if the path is relative to another path or False.
         """
-        if not other:
-            raise TypeError("need at least one argument")
-        other = type(self)(*other)
+        if _deprecated:
+            msg = ("support for supplying more than one argument to "
+                   "pathlib.PurePath.is_relative_to() is deprecated and "
+                   "scheduled for removal in Python {remove}")
+            warnings._deprecated("pathlib.PurePath.is_relative_to(*args)",
+                                 msg, remove=(3, 14))
+        other = type(self)(other, *_deprecated)
         return other == self or other in self.parents
 
     @property
index 1d01d3cbd91d1498731680209b218422a8f077e9..fa6ea0ac63d8da16c1e19db452f5b1ada8d71993 100644 (file)
@@ -654,8 +654,9 @@ class _BasePurePathTest(object):
         self.assertEqual(p.relative_to(P('c'), walk_up=True), P('../a/b'))
         self.assertEqual(p.relative_to('c', walk_up=True), P('../a/b'))
         # With several args.
-        self.assertEqual(p.relative_to('a', 'b'), P())
-        self.assertEqual(p.relative_to('a', 'b', walk_up=True), P())
+        with self.assertWarns(DeprecationWarning):
+            p.relative_to('a', 'b')
+            p.relative_to('a', 'b', walk_up=True)
         # Unrelated paths.
         self.assertRaises(ValueError, p.relative_to, P('c'))
         self.assertRaises(ValueError, p.relative_to, P('a/b/c'))
@@ -706,7 +707,8 @@ class _BasePurePathTest(object):
         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'))
+        with self.assertWarns(DeprecationWarning):
+            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')))
diff --git a/Misc/NEWS.d/next/Library/2022-07-01-00-01-22.gh-issue-78707.fHGSuM.rst b/Misc/NEWS.d/next/Library/2022-07-01-00-01-22.gh-issue-78707.fHGSuM.rst
new file mode 100644 (file)
index 0000000..c490a3c
--- /dev/null
@@ -0,0 +1,3 @@
+Deprecate passing more than one positional argument to
+:meth:`pathlib.PurePath.relative_to` and
+:meth:`~pathlib.PurePath.is_relative_to`.