Skip to content

Commit a51baec

Browse files
gh-92550 - Fix regression in pathlib.Path.rglob() (GH-92583)
We could try to remedy this by taking a slice, but we then run into an issue where the empty string will match altsep on POSIX. That rabbit hole could keep getting deeper. A proper fix for the original issue involves making pathlib's path normalisation more configurable - in this case we want to retain trailing slashes, but in other we might want to preserve `./` prefixes, or elide `../` segments when we're sure we won't encounter symlinks. This reverts commit ea2f5bc. (cherry picked from commit dcdf250) Co-authored-by: Barney Gale <barney.gale@gmail.com>
1 parent a86229e commit a51baec

File tree

5 files changed

+2
-38
lines changed

5 files changed

+2
-38
lines changed

Doc/library/pathlib.rst

-6
Original file line numberDiff line numberDiff line change
@@ -815,9 +815,6 @@ call fails (for example because the path doesn't exist).
815815

816816
.. audit-event:: pathlib.Path.glob self,pattern pathlib.Path.glob
817817

818-
.. versionchanged:: 3.11
819-
Return only directories if *pattern* ends with a pathname components
820-
separator (:data:`~os.sep` or :data:`~os.altsep`).
821818

822819
.. method:: Path.group()
823820

@@ -1107,9 +1104,6 @@ call fails (for example because the path doesn't exist).
11071104

11081105
.. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob
11091106

1110-
.. versionchanged:: 3.11
1111-
Return only directories if *pattern* ends with a pathname components
1112-
separator (:data:`~os.sep` or :data:`~os.altsep`).
11131107

11141108
.. method:: Path.rmdir()
11151109

Doc/whatsnew/3.11.rst

-9
Original file line numberDiff line numberDiff line change
@@ -557,15 +557,6 @@ os
557557
instead of ``CryptGenRandom()`` which is deprecated.
558558
(Contributed by Dong-hee Na in :issue:`44611`.)
559559

560-
561-
pathlib
562-
-------
563-
564-
* :meth:`~pathlib.Path.glob` and :meth:`~pathlib.Path.rglob` return only
565-
directories if *pattern* ends with a pathname components separator:
566-
:data:`~os.sep` or :data:`~os.altsep`.
567-
(Contributed by Eisuke Kawasima in :issue:`22276` and :issue:`33392`.)
568-
569560
re
570561
--
571562

Lib/pathlib.py

-6
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,6 @@ def make_uri(self, path):
281281
def _make_selector(pattern_parts, flavour):
282282
pat = pattern_parts[0]
283283
child_parts = pattern_parts[1:]
284-
if not pat:
285-
return _TerminatingSelector()
286284
if pat == '**':
287285
cls = _RecursiveWildcardSelector
288286
elif '**' in pat:
@@ -945,8 +943,6 @@ def glob(self, pattern):
945943
drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
946944
if drv or root:
947945
raise NotImplementedError("Non-relative patterns are unsupported")
948-
if pattern[-1] in (self._flavour.sep, self._flavour.altsep):
949-
pattern_parts.append('')
950946
selector = _make_selector(tuple(pattern_parts), self._flavour)
951947
for p in selector.select_from(self):
952948
yield p
@@ -960,8 +956,6 @@ def rglob(self, pattern):
960956
drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
961957
if drv or root:
962958
raise NotImplementedError("Non-relative patterns are unsupported")
963-
if pattern[-1] in (self._flavour.sep, self._flavour.altsep):
964-
pattern_parts.append('')
965959
selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour)
966960
for p in selector.select_from(self):
967961
yield p

Lib/test/test_pathlib.py

-17
Original file line numberDiff line numberDiff line change
@@ -1662,11 +1662,6 @@ def _check(glob, expected):
16621662
else:
16631663
_check(p.glob("*/fileB"), ['dirB/fileB', 'linkB/fileB'])
16641664

1665-
if not os_helper.can_symlink():
1666-
_check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE"])
1667-
else:
1668-
_check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE", "linkB"])
1669-
16701665
def test_rglob_common(self):
16711666
def _check(glob, expected):
16721667
self.assertEqual(set(glob), { P(BASE, q) for q in expected })
@@ -1684,16 +1679,6 @@ def _check(glob, expected):
16841679
"linkB/fileB", "dirA/linkC/fileB"])
16851680
_check(p.rglob("file*"), ["fileA", "dirB/fileB",
16861681
"dirC/fileC", "dirC/dirD/fileD"])
1687-
if not os_helper.can_symlink():
1688-
_check(p.rglob("*/"), [
1689-
"dirA", "dirB", "dirC", "dirC/dirD", "dirE",
1690-
])
1691-
else:
1692-
_check(p.rglob("*/"), [
1693-
"dirA", "dirA/linkC", "dirB", "dirB/linkD", "dirC",
1694-
"dirC/dirD", "dirE", "linkB",
1695-
])
1696-
16971682
p = P(BASE, "dirC")
16981683
_check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
16991684
_check(p.rglob("*/*"), ["dirC/dirD/fileD"])
@@ -2719,7 +2704,6 @@ def test_glob(self):
27192704
P = self.cls
27202705
p = P(BASE)
27212706
self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") })
2722-
self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA") })
27232707
self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") })
27242708
self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\FILEa"})
27252709
self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"})
@@ -2728,7 +2712,6 @@ def test_rglob(self):
27282712
P = self.cls
27292713
p = P(BASE, "dirC")
27302714
self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") })
2731-
self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD") })
27322715
self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\FILEd"})
27332716

27342717
def test_expanduser(self):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:meth:`pathlib.Path.rglob` raised :exc:`IndexError` when called with an
2+
empty string. This regression was introduced in 3.11b1.

0 commit comments

Comments
 (0)