]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-93156 - fix negative indexing into absolute `pathlib.PurePath().parents` (GH-93273)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 3 Jun 2022 21:53:00 +0000 (14:53 -0700)
committerGitHub <noreply@github.com>
Fri, 3 Jun 2022 21:53:00 +0000 (14:53 -0700)
When a `_PathParents` object has a drive or a root, the length of the
object is *one less* than than the length of `self._parts`, which resulted
in an off-by-one error when `path.parents[-n]` was fed through to
`self._parts[:-n - 1]`. In particular, `path.parents[-1]` was a malformed
path object with spooky properties.

This is addressed by adding `len(self)` to negative indices.
(cherry picked from commit f32e6b48d12834ba3bde01ec21c14da33abd26d6)

Co-authored-by: Barney Gale <barney.gale@gmail.com>
Lib/pathlib.py
Lib/test/test_pathlib.py
Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst [new file with mode: 0644]

index 621fba0e75c0f7c085ff61810640b0e2e791c737..97b23ca45a3a19ccb7824c2b7232730f4860e4e8 100644 (file)
@@ -528,6 +528,8 @@ class _PathParents(Sequence):
 
         if idx >= len(self) or idx < -len(self):
             raise IndexError(idx)
+        if idx < 0:
+            idx += len(self)
         return self._pathcls._from_parsed_parts(self._drv, self._root,
                                                 self._parts[:-idx - 1])
 
index 555c7ee795bd12cc73b8573dbda96abdef60428e..bf3fc5fb249d212090dcbbb8c4a761f6b3b0de26 100644 (file)
@@ -463,6 +463,9 @@ class _BasePurePathTest(object):
         self.assertEqual(par[0], P('/a/b'))
         self.assertEqual(par[1], P('/a'))
         self.assertEqual(par[2], P('/'))
+        self.assertEqual(par[-1], P('/'))
+        self.assertEqual(par[-2], P('/a'))
+        self.assertEqual(par[-3], P('/a/b'))
         self.assertEqual(par[0:1], (P('/a/b'),))
         self.assertEqual(par[:2], (P('/a/b'), P('/a')))
         self.assertEqual(par[:-1], (P('/a/b'), P('/a')))
@@ -470,6 +473,8 @@ class _BasePurePathTest(object):
         self.assertEqual(par[::2], (P('/a/b'), P('/')))
         self.assertEqual(par[::-1], (P('/'), P('/a'), P('/a/b')))
         self.assertEqual(list(par), [P('/a/b'), P('/a'), P('/')])
+        with self.assertRaises(IndexError):
+            par[-4]
         with self.assertRaises(IndexError):
             par[3]
 
diff --git a/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst b/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst
new file mode 100644 (file)
index 0000000..165baa0
--- /dev/null
@@ -0,0 +1,2 @@
+Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path
+using negative index values produced incorrect results.