Skip to content

Commit 6f07016

Browse files
authored
GH-127381: pathlib ABCs: remove ReadablePath.rglob() (#130207)
Remove `ReadablePath.rglob()` from the private pathlib ABCs. This method is a trivial wrapper around `glob()` and easily replaced.
1 parent 7fcace9 commit 6f07016

File tree

3 files changed

+58
-68
lines changed

3 files changed

+58
-68
lines changed

Lib/pathlib/_abc.py

-10
Original file line numberDiff line numberDiff line change
@@ -302,16 +302,6 @@ def glob(self, pattern, *, case_sensitive=None, recurse_symlinks=True):
302302
select = globber.selector(parts)
303303
return select(self.joinpath(''))
304304

305-
def rglob(self, pattern, *, case_sensitive=None, recurse_symlinks=True):
306-
"""Recursively yield all existing files (of any kind, including
307-
directories) matching the given relative pattern, anywhere in
308-
this subtree.
309-
"""
310-
if not isinstance(pattern, JoinablePath):
311-
pattern = self.with_segments(pattern)
312-
pattern = '**' / pattern
313-
return self.glob(pattern, case_sensitive=case_sensitive, recurse_symlinks=recurse_symlinks)
314-
315305
def walk(self, top_down=True, on_error=None, follow_symlinks=False):
316306
"""Walk the directory tree from this directory, similar to os.walk()."""
317307
paths = [self]

Lib/test/test_pathlib/test_pathlib.py

+58
Original file line numberDiff line numberDiff line change
@@ -2766,6 +2766,64 @@ def _check(path, glob, expected):
27662766
_check(p, "*.txt", ["dirC/novel.txt"])
27672767
_check(p, "*.*", ["dirC/novel.txt"])
27682768

2769+
def test_rglob_recurse_symlinks_false(self):
2770+
def _check(path, glob, expected):
2771+
actual = set(path.rglob(glob, recurse_symlinks=False))
2772+
self.assertEqual(actual, { P(self.base, q) for q in expected })
2773+
P = self.cls
2774+
p = P(self.base)
2775+
it = p.rglob("fileA")
2776+
self.assertIsInstance(it, collections.abc.Iterator)
2777+
_check(p, "fileA", ["fileA"])
2778+
_check(p, "fileB", ["dirB/fileB"])
2779+
_check(p, "**/fileB", ["dirB/fileB"])
2780+
_check(p, "*/fileA", [])
2781+
2782+
if self.can_symlink:
2783+
_check(p, "*/fileB", ["dirB/fileB", "dirB/linkD/fileB",
2784+
"linkB/fileB", "dirA/linkC/fileB"])
2785+
_check(p, "*/", [
2786+
"dirA/", "dirA/linkC/", "dirB/", "dirB/linkD/", "dirC/",
2787+
"dirC/dirD/", "dirE/", "linkB/"])
2788+
else:
2789+
_check(p, "*/fileB", ["dirB/fileB"])
2790+
_check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"])
2791+
2792+
_check(p, "file*", ["fileA", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD"])
2793+
_check(p, "", ["", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"])
2794+
p = P(self.base, "dirC")
2795+
_check(p, "*", ["dirC/fileC", "dirC/novel.txt",
2796+
"dirC/dirD", "dirC/dirD/fileD"])
2797+
_check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"])
2798+
_check(p, "**/file*", ["dirC/fileC", "dirC/dirD/fileD"])
2799+
_check(p, "dir*/**", ["dirC/dirD/", "dirC/dirD/fileD"])
2800+
_check(p, "dir*/**/", ["dirC/dirD/"])
2801+
_check(p, "*/*", ["dirC/dirD/fileD"])
2802+
_check(p, "*/", ["dirC/dirD/"])
2803+
_check(p, "", ["dirC/", "dirC/dirD/"])
2804+
_check(p, "**", ["dirC/", "dirC/fileC", "dirC/dirD", "dirC/dirD/fileD", "dirC/novel.txt"])
2805+
_check(p, "**/", ["dirC/", "dirC/dirD/"])
2806+
# gh-91616, a re module regression
2807+
_check(p, "*.txt", ["dirC/novel.txt"])
2808+
_check(p, "*.*", ["dirC/novel.txt"])
2809+
2810+
@needs_posix
2811+
def test_rglob_posix(self):
2812+
P = self.cls
2813+
p = P(self.base, "dirC")
2814+
q = p / "dirD" / "FILEd"
2815+
given = set(p.rglob("FILEd"))
2816+
expect = {q} if q.exists() else set()
2817+
self.assertEqual(given, expect)
2818+
self.assertEqual(set(p.rglob("FILEd*")), set())
2819+
2820+
@needs_windows
2821+
def test_rglob_windows(self):
2822+
P = self.cls
2823+
p = P(self.base, "dirC")
2824+
self.assertEqual(set(p.rglob("FILEd")), { P(self.base, "dirC/dirD/fileD") })
2825+
self.assertEqual(set(p.rglob("*\\")), { P(self.base, "dirC/dirD/") })
2826+
27692827
@needs_symlinks
27702828
def test_rglob_symlink_loop(self):
27712829
# Don't get fooled by symlink loops (Issue #26012).

Lib/test/test_pathlib/test_pathlib_abc.py

-58
Original file line numberDiff line numberDiff line change
@@ -1136,64 +1136,6 @@ def _check(path, pattern, case_sensitive, expected):
11361136
_check(path, "dirb/file*", True, [])
11371137
_check(path, "dirb/file*", False, ["dirB/fileB"])
11381138

1139-
def test_rglob_recurse_symlinks_false(self):
1140-
def _check(path, glob, expected):
1141-
actual = set(path.rglob(glob, recurse_symlinks=False))
1142-
self.assertEqual(actual, { P(self.base, q) for q in expected })
1143-
P = self.cls
1144-
p = P(self.base)
1145-
it = p.rglob("fileA")
1146-
self.assertIsInstance(it, collections.abc.Iterator)
1147-
_check(p, "fileA", ["fileA"])
1148-
_check(p, "fileB", ["dirB/fileB"])
1149-
_check(p, "**/fileB", ["dirB/fileB"])
1150-
_check(p, "*/fileA", [])
1151-
1152-
if self.can_symlink:
1153-
_check(p, "*/fileB", ["dirB/fileB", "dirB/linkD/fileB",
1154-
"linkB/fileB", "dirA/linkC/fileB"])
1155-
_check(p, "*/", [
1156-
"dirA/", "dirA/linkC/", "dirB/", "dirB/linkD/", "dirC/",
1157-
"dirC/dirD/", "dirE/", "linkB/"])
1158-
else:
1159-
_check(p, "*/fileB", ["dirB/fileB"])
1160-
_check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"])
1161-
1162-
_check(p, "file*", ["fileA", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD"])
1163-
_check(p, "", ["", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"])
1164-
p = P(self.base, "dirC")
1165-
_check(p, "*", ["dirC/fileC", "dirC/novel.txt",
1166-
"dirC/dirD", "dirC/dirD/fileD"])
1167-
_check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"])
1168-
_check(p, "**/file*", ["dirC/fileC", "dirC/dirD/fileD"])
1169-
_check(p, "dir*/**", ["dirC/dirD/", "dirC/dirD/fileD"])
1170-
_check(p, "dir*/**/", ["dirC/dirD/"])
1171-
_check(p, "*/*", ["dirC/dirD/fileD"])
1172-
_check(p, "*/", ["dirC/dirD/"])
1173-
_check(p, "", ["dirC/", "dirC/dirD/"])
1174-
_check(p, "**", ["dirC/", "dirC/fileC", "dirC/dirD", "dirC/dirD/fileD", "dirC/novel.txt"])
1175-
_check(p, "**/", ["dirC/", "dirC/dirD/"])
1176-
# gh-91616, a re module regression
1177-
_check(p, "*.txt", ["dirC/novel.txt"])
1178-
_check(p, "*.*", ["dirC/novel.txt"])
1179-
1180-
@needs_posix
1181-
def test_rglob_posix(self):
1182-
P = self.cls
1183-
p = P(self.base, "dirC")
1184-
q = p / "dirD" / "FILEd"
1185-
given = set(p.rglob("FILEd"))
1186-
expect = {q} if q.exists() else set()
1187-
self.assertEqual(given, expect)
1188-
self.assertEqual(set(p.rglob("FILEd*")), set())
1189-
1190-
@needs_windows
1191-
def test_rglob_windows(self):
1192-
P = self.cls
1193-
p = P(self.base, "dirC")
1194-
self.assertEqual(set(p.rglob("FILEd")), { P(self.base, "dirC/dirD/fileD") })
1195-
self.assertEqual(set(p.rglob("*\\")), { P(self.base, "dirC/dirD/") })
1196-
11971139
def test_info_exists(self):
11981140
p = self.cls(self.base)
11991141
self.assertTrue(p.info.exists())

0 commit comments

Comments
 (0)