From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 3 Jun 2022 21:53:00 +0000 (-0700) Subject: gh-93156 - fix negative indexing into absolute `pathlib.PurePath().parents` (GH-93273) X-Git-Tag: v3.10.5~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b382bf50c53e6eab09f3e3bf0802ab052cb0289d;p=thirdparty%2FPython%2Fcpython.git gh-93156 - fix negative indexing into absolute `pathlib.PurePath().parents` (GH-93273) 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 --- diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 621fba0e75c0..97b23ca45a3a 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -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]) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 555c7ee795bd..bf3fc5fb249d 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -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 index 000000000000..165baa08aaab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst @@ -0,0 +1,2 @@ +Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path +using negative index values produced incorrect results.