[Python-checkins] gh-92550 - Fix regression in `pathlib.Path.rglob()` (GH-92583)
miss-islington
webhook-mailer at python.org
Mon May 9 20:39:48 EDT 2022
https://github.com/python/cpython/commit/a51baec9ce0eae2b4db069a55daf8f03be3ab2f4
commit: a51baec9ce0eae2b4db069a55daf8f03be3ab2f4
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-05-09T17:39:43-07:00
summary:
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 ea2f5bcda1a392804487e6883be89fbad38a01a5.
(cherry picked from commit dcdf250d2de1428f7d8b4e9ecf51d2fd8200e21a)
Co-authored-by: Barney Gale <barney.gale at gmail.com>
files:
A Misc/NEWS.d/next/Library/2022-05-09-23-36-19.gh-issue-92550.qZ4AhU.rst
M Doc/library/pathlib.rst
M Doc/whatsnew/3.11.rst
M Lib/pathlib.py
M Lib/test/test_pathlib.py
diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst
index ab26e2f1719fe..01e9cfb93e391 100644
--- a/Doc/library/pathlib.rst
+++ b/Doc/library/pathlib.rst
@@ -815,9 +815,6 @@ call fails (for example because the path doesn't exist).
.. audit-event:: pathlib.Path.glob self,pattern pathlib.Path.glob
- .. versionchanged:: 3.11
- Return only directories if *pattern* ends with a pathname components
- separator (:data:`~os.sep` or :data:`~os.altsep`).
.. method:: Path.group()
@@ -1107,9 +1104,6 @@ call fails (for example because the path doesn't exist).
.. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob
- .. versionchanged:: 3.11
- Return only directories if *pattern* ends with a pathname components
- separator (:data:`~os.sep` or :data:`~os.altsep`).
.. method:: Path.rmdir()
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index fd7082e9fd74d..ed61e01f9c38e 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -557,15 +557,6 @@ os
instead of ``CryptGenRandom()`` which is deprecated.
(Contributed by Dong-hee Na in :issue:`44611`.)
-
-pathlib
--------
-
-* :meth:`~pathlib.Path.glob` and :meth:`~pathlib.Path.rglob` return only
- directories if *pattern* ends with a pathname components separator:
- :data:`~os.sep` or :data:`~os.altsep`.
- (Contributed by Eisuke Kawasima in :issue:`22276` and :issue:`33392`.)
-
re
--
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
index 1f098fe6bd5f3..4763ab54f6ba8 100644
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -281,8 +281,6 @@ def make_uri(self, path):
def _make_selector(pattern_parts, flavour):
pat = pattern_parts[0]
child_parts = pattern_parts[1:]
- if not pat:
- return _TerminatingSelector()
if pat == '**':
cls = _RecursiveWildcardSelector
elif '**' in pat:
@@ -945,8 +943,6 @@ def glob(self, pattern):
drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
if drv or root:
raise NotImplementedError("Non-relative patterns are unsupported")
- if pattern[-1] in (self._flavour.sep, self._flavour.altsep):
- pattern_parts.append('')
selector = _make_selector(tuple(pattern_parts), self._flavour)
for p in selector.select_from(self):
yield p
@@ -960,8 +956,6 @@ def rglob(self, pattern):
drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
if drv or root:
raise NotImplementedError("Non-relative patterns are unsupported")
- if pattern[-1] in (self._flavour.sep, self._flavour.altsep):
- pattern_parts.append('')
selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour)
for p in selector.select_from(self):
yield p
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
index 6737068c0ff6d..b8b08bf0ce1bb 100644
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1662,11 +1662,6 @@ def _check(glob, expected):
else:
_check(p.glob("*/fileB"), ['dirB/fileB', 'linkB/fileB'])
- if not os_helper.can_symlink():
- _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE"])
- else:
- _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE", "linkB"])
-
def test_rglob_common(self):
def _check(glob, expected):
self.assertEqual(set(glob), { P(BASE, q) for q in expected })
@@ -1684,16 +1679,6 @@ def _check(glob, expected):
"linkB/fileB", "dirA/linkC/fileB"])
_check(p.rglob("file*"), ["fileA", "dirB/fileB",
"dirC/fileC", "dirC/dirD/fileD"])
- if not os_helper.can_symlink():
- _check(p.rglob("*/"), [
- "dirA", "dirB", "dirC", "dirC/dirD", "dirE",
- ])
- else:
- _check(p.rglob("*/"), [
- "dirA", "dirA/linkC", "dirB", "dirB/linkD", "dirC",
- "dirC/dirD", "dirE", "linkB",
- ])
-
p = P(BASE, "dirC")
_check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
_check(p.rglob("*/*"), ["dirC/dirD/fileD"])
@@ -2719,7 +2704,6 @@ def test_glob(self):
P = self.cls
p = P(BASE)
self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") })
- self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA") })
self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") })
self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\FILEa"})
self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"})
@@ -2728,7 +2712,6 @@ def test_rglob(self):
P = self.cls
p = P(BASE, "dirC")
self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") })
- self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD") })
self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\FILEd"})
def test_expanduser(self):
diff --git a/Misc/NEWS.d/next/Library/2022-05-09-23-36-19.gh-issue-92550.qZ4AhU.rst b/Misc/NEWS.d/next/Library/2022-05-09-23-36-19.gh-issue-92550.qZ4AhU.rst
new file mode 100644
index 0000000000000..1931b329b3c6e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-05-09-23-36-19.gh-issue-92550.qZ4AhU.rst
@@ -0,0 +1,2 @@
+:meth:`pathlib.Path.rglob` raised :exc:`IndexError` when called with an
+empty string. This regression was introduced in 3.11b1.
More information about the Python-checkins
mailing list