From 452058448335b39c784af9a047f9c4a1767c0b00 Mon Sep 17 00:00:00 2001 From: Joshua Cannon Date: Fri, 20 Nov 2020 09:40:39 -0600 Subject: [PATCH] bpo-35498: Added slice support to PathLib parents attribute. (GH-11165) Added slice support to the `pathlib.Path.parents` sequence. For a `Path` `p`, slices of `p.parents` should return the same thing as slices of `tuple(p.parents)`. --- Doc/library/pathlib.rst | 2 ++ Doc/whatsnew/3.10.rst | 6 ++++ Lib/pathlib.py | 2 ++ Lib/test/test_pathlib.py | 30 +++++++++++++++++++ Misc/ACKS | 1 + .../2018-12-14-13-29-17.bpo-35498.LEJHl7.rst | 1 + 6 files changed, 42 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-12-14-13-29-17.bpo-35498.LEJHl7.rst diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 9de72bb725c..2071e7ed5f4 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -336,6 +336,8 @@ Pure paths provide the following methods and properties: >>> p.parents[2] PureWindowsPath('c:/') + .. versionchanged:: 3.10 + Slice support was added. .. data:: PurePath.parent diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 826d12704a1..16cb7efe298 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -244,6 +244,12 @@ descriptors without copying between kernel address space and user address space, where one of the file descriptors must refer to a pipe. (Contributed by Pablo Galindo in :issue:`41625`.) +pathlib +------- + +Added slice support to :meth:`~pathlib.Path.parents`. +(Contributed by Joshua Cannon in :issue:`35498`) + py_compile ---------- diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 178c5b981d8..af310393c3e 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -630,6 +630,8 @@ class _PathParents(Sequence): return len(self._parts) def __getitem__(self, idx): + if isinstance(idx, slice): + return tuple(self[i] for i in range(*idx.indices(len(self)))) if idx < 0 or idx >= len(self): raise IndexError(idx) return self._pathcls._from_parsed_parts(self._drv, self._root, diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 17292dc1abf..f1451796b64 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -440,6 +440,12 @@ class _BasePurePathTest(object): self.assertEqual(par[0], P('a/b')) self.assertEqual(par[1], P('a')) self.assertEqual(par[2], P('.')) + 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'))) + self.assertEqual(par[1:], (P('a'), P('.'))) + 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[-1] @@ -454,6 +460,12 @@ class _BasePurePathTest(object): self.assertEqual(par[0], P('/a/b')) self.assertEqual(par[1], P('/a')) self.assertEqual(par[2], P('/')) + 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'))) + self.assertEqual(par[1:], (P('/a'), P('/'))) + 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[3] @@ -905,6 +917,12 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(len(par), 2) self.assertEqual(par[0], P('z:a')) self.assertEqual(par[1], P('z:')) + self.assertEqual(par[0:1], (P('z:a'),)) + self.assertEqual(par[:-1], (P('z:a'),)) + self.assertEqual(par[:2], (P('z:a'), P('z:'))) + self.assertEqual(par[1:], (P('z:'),)) + self.assertEqual(par[::2], (P('z:a'),)) + self.assertEqual(par[::-1], (P('z:'), P('z:a'))) self.assertEqual(list(par), [P('z:a'), P('z:')]) with self.assertRaises(IndexError): par[2] @@ -913,6 +931,12 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(len(par), 2) self.assertEqual(par[0], P('z:/a')) self.assertEqual(par[1], P('z:/')) + self.assertEqual(par[0:1], (P('z:/a'),)) + self.assertEqual(par[0:-1], (P('z:/a'),)) + self.assertEqual(par[:2], (P('z:/a'), P('z:/'))) + self.assertEqual(par[1:], (P('z:/'),)) + self.assertEqual(par[::2], (P('z:/a'),)) + self.assertEqual(par[::-1], (P('z:/'), P('z:/a'),)) self.assertEqual(list(par), [P('z:/a'), P('z:/')]) with self.assertRaises(IndexError): par[2] @@ -921,6 +945,12 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(len(par), 2) self.assertEqual(par[0], P('//a/b/c')) self.assertEqual(par[1], P('//a/b')) + self.assertEqual(par[0:1], (P('//a/b/c'),)) + self.assertEqual(par[0:-1], (P('//a/b/c'),)) + self.assertEqual(par[:2], (P('//a/b/c'), P('//a/b'))) + self.assertEqual(par[1:], (P('//a/b'),)) + self.assertEqual(par[::2], (P('//a/b/c'),)) + self.assertEqual(par[::-1], (P('//a/b'), P('//a/b/c'))) self.assertEqual(list(par), [P('//a/b/c'), P('//a/b')]) with self.assertRaises(IndexError): par[2] diff --git a/Misc/ACKS b/Misc/ACKS index 1d106144d46..43030caae66 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -270,6 +270,7 @@ Daniel Calvelo Tony Campbell Giovanni Cappellotto Brett Cannon +Joshua Cannon Tristan Carel Mike Carlton Pierre Carrier diff --git a/Misc/NEWS.d/next/Library/2018-12-14-13-29-17.bpo-35498.LEJHl7.rst b/Misc/NEWS.d/next/Library/2018-12-14-13-29-17.bpo-35498.LEJHl7.rst new file mode 100644 index 00000000000..fb24ce027c2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-14-13-29-17.bpo-35498.LEJHl7.rst @@ -0,0 +1 @@ +Add slice support to :meth:`~pathlib.Path.parents`.