]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-70303: Emit FutureWarning when pathlib glob pattern ends with `**` (GH-105413)
authorBarney Gale <barney.gale@gmail.com>
Fri, 4 Aug 2023 23:12:12 +0000 (00:12 +0100)
committerGitHub <noreply@github.com>
Fri, 4 Aug 2023 23:12:12 +0000 (23:12 +0000)
In a future Python release, patterns with this ending will match both files
and directories. Users may add a trailing slash to remove the warning.

Doc/library/pathlib.rst
Lib/pathlib.py
Lib/test/test_pathlib.py
Misc/NEWS.d/next/Library/2023-06-07-00-13-00.gh-issue-70303.frwUKH.rst [new file with mode: 0644]

index 01dabe286969bb5cb6ad7c9561f72925f1d558e4..22360b22fd924b2570071e813b7c8d60a215c5b8 100644 (file)
@@ -976,6 +976,11 @@ call fails (for example because the path doesn't exist).
    .. versionchanged:: 3.13
       The *follow_symlinks* parameter was added.
 
+   .. versionchanged:: 3.13
+      Emits :exc:`FutureWarning` if the pattern ends with "``**``". In a
+      future Python release, patterns with this ending will match both files
+      and directories. Add a trailing slash to match only directories.
+
 .. method:: Path.group()
 
    Return the name of the group owning the file.  :exc:`KeyError` is raised
index c83cf3d2ef696d41049a6c7653a939a3181b9e40..758f70f5ba7077591784ded11b0d2df4bd6e4e5a 100644 (file)
@@ -1069,6 +1069,11 @@ class Path(PurePath):
             pattern_parts.append('')
         if pattern_parts[-1] == '**':
             # GH-70303: '**' only matches directories. Add trailing slash.
+            warnings.warn(
+                "Pattern ending '**' will match files and directories in a "
+                "future Python release. Add a trailing slash to match only "
+                "directories and remove this warning.",
+                FutureWarning, 3)
             pattern_parts.append('')
 
         if case_sensitive is None:
index 5789a932c590376bc9b482bc67288a396fbde8ad..74deec84336f725e0d0b5734b9ba8432a4a19890 100644 (file)
@@ -1903,11 +1903,11 @@ class PathTest(unittest.TestCase):
                               "dirC/dirD", "dirC/dirD/fileD"])
         _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
         _check(p.rglob("**/file*"), ["dirC/fileC", "dirC/dirD/fileD"])
-        _check(p.rglob("dir*/**"), ["dirC/dirD"])
+        _check(p.rglob("dir*/**/"), ["dirC/dirD"])
         _check(p.rglob("*/*"), ["dirC/dirD/fileD"])
         _check(p.rglob("*/"), ["dirC/dirD"])
         _check(p.rglob(""), ["dirC", "dirC/dirD"])
-        _check(p.rglob("**"), ["dirC", "dirC/dirD"])
+        _check(p.rglob("**/"), ["dirC", "dirC/dirD"])
         # gh-91616, a re module regression
         _check(p.rglob("*.txt"), ["dirC/novel.txt"])
         _check(p.rglob("*.*"), ["dirC/novel.txt"])
@@ -2057,7 +2057,20 @@ class PathTest(unittest.TestCase):
         path.mkdir(parents=True)
 
         with set_recursion_limit(recursion_limit):
-            list(base.glob('**'))
+            list(base.glob('**/'))
+
+    def test_glob_recursive_no_trailing_slash(self):
+        P = self.cls
+        p = P(BASE)
+        with self.assertWarns(FutureWarning):
+            p.glob('**')
+        with self.assertWarns(FutureWarning):
+            p.glob('*/**')
+        with self.assertWarns(FutureWarning):
+            p.rglob('**')
+        with self.assertWarns(FutureWarning):
+            p.rglob('*/**')
+
 
     def test_readlink(self):
         if not self.can_symlink:
diff --git a/Misc/NEWS.d/next/Library/2023-06-07-00-13-00.gh-issue-70303.frwUKH.rst b/Misc/NEWS.d/next/Library/2023-06-07-00-13-00.gh-issue-70303.frwUKH.rst
new file mode 100644 (file)
index 0000000..39a891a
--- /dev/null
@@ -0,0 +1,4 @@
+Emit :exc:`FutureWarning` from :meth:`pathlib.Path.glob` and
+:meth:`~pathlib.Path.rglob` if the given pattern ends with "``**``". In a
+future Python release, patterns with this ending will match both files and
+directories. Add a trailing slash to only match directories.