]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-92550 - Fix regression in `pathlib.Path.rglob()` (GH-92583)
authorBarney Gale <barney.gale@gmail.com>
Tue, 10 May 2022 00:12:16 +0000 (01:12 +0100)
committerGitHub <noreply@github.com>
Tue, 10 May 2022 00:12:16 +0000 (17:12 -0700)
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.

Doc/library/pathlib.rst
Doc/whatsnew/3.11.rst
Lib/pathlib.py
Lib/test/test_pathlib.py
Misc/NEWS.d/next/Library/2022-05-09-23-36-19.gh-issue-92550.qZ4AhU.rst [new file with mode: 0644]

index ab26e2f1719fe9c9582866d502f3303cce1814c6..01e9cfb93e391127d8881a02f277b7191242ec82 100644 (file)
@@ -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()
 
index fd7082e9fd74d22e38f7f7d8b272ff93c561492c..ed61e01f9c38ed2782f5c3a590d3d96d42e185e8 100644 (file)
@@ -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
 --
 
index 1f098fe6bd5f37b5440f8a764ba3f645e2889784..4763ab54f6ba81f21eb0a43d7719bb46a68cf2ce 100644 (file)
@@ -281,8 +281,6 @@ _posix_flavour = _PosixFlavour()
 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 @@ class Path(PurePath):
         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 @@ class Path(PurePath):
         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
index 6737068c0ff6d6c56fe7a7ec63b01e4a978a07fe..b8b08bf0ce1bb598596da814e643263f7dba6060 100644 (file)
@@ -1662,11 +1662,6 @@ class _BasePathTest(object):
         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 @@ class _BasePathTest(object):
                                         "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 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase):
         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 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase):
         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 (file)
index 0000000..1931b32
--- /dev/null
@@ -0,0 +1,2 @@
+:meth:`pathlib.Path.rglob` raised :exc:`IndexError` when called with an
+empty string. This regression was introduced in 3.11b1.