Skip to content

Commit f32e6b4

Browse files
authored
pythongh-93156 - fix negative indexing into absolute pathlib.PurePath().parents (pythonGH-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.
1 parent 1a8a0dd commit f32e6b4

File tree

3 files changed

+9
-0
lines changed

3 files changed

+9
-0
lines changed

Lib/pathlib.py

+2
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,8 @@ def __getitem__(self, idx):
443443

444444
if idx >= len(self) or idx < -len(self):
445445
raise IndexError(idx)
446+
if idx < 0:
447+
idx += len(self)
446448
return self._pathcls._from_parsed_parts(self._drv, self._root,
447449
self._parts[:-idx - 1])
448450

Lib/test/test_pathlib.py

+5
Original file line numberDiff line numberDiff line change
@@ -465,13 +465,18 @@ def test_parents_common(self):
465465
self.assertEqual(par[0], P('/a/b'))
466466
self.assertEqual(par[1], P('/a'))
467467
self.assertEqual(par[2], P('/'))
468+
self.assertEqual(par[-1], P('/'))
469+
self.assertEqual(par[-2], P('/a'))
470+
self.assertEqual(par[-3], P('/a/b'))
468471
self.assertEqual(par[0:1], (P('/a/b'),))
469472
self.assertEqual(par[:2], (P('/a/b'), P('/a')))
470473
self.assertEqual(par[:-1], (P('/a/b'), P('/a')))
471474
self.assertEqual(par[1:], (P('/a'), P('/')))
472475
self.assertEqual(par[::2], (P('/a/b'), P('/')))
473476
self.assertEqual(par[::-1], (P('/'), P('/a'), P('/a/b')))
474477
self.assertEqual(list(par), [P('/a/b'), P('/a'), P('/')])
478+
with self.assertRaises(IndexError):
479+
par[-4]
475480
with self.assertRaises(IndexError):
476481
par[3]
477482

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path
2+
using negative index values produced incorrect results.

0 commit comments

Comments
 (0)