Skip to content

Commit ec0a0d2

Browse files
authored
GH-70303: Emit FutureWarning when pathlib glob pattern ends with ** (GH-105413)
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.
1 parent 2c25bd8 commit ec0a0d2

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

Doc/library/pathlib.rst

+5
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,11 @@ call fails (for example because the path doesn't exist).
976976
.. versionchanged:: 3.13
977977
The *follow_symlinks* parameter was added.
978978

979+
.. versionchanged:: 3.13
980+
Emits :exc:`FutureWarning` if the pattern ends with "``**``". In a
981+
future Python release, patterns with this ending will match both files
982+
and directories. Add a trailing slash to match only directories.
983+
979984
.. method:: Path.group()
980985

981986
Return the name of the group owning the file. :exc:`KeyError` is raised

Lib/pathlib.py

+5
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,11 @@ def _glob(self, pattern, case_sensitive, follow_symlinks):
10691069
pattern_parts.append('')
10701070
if pattern_parts[-1] == '**':
10711071
# GH-70303: '**' only matches directories. Add trailing slash.
1072+
warnings.warn(
1073+
"Pattern ending '**' will match files and directories in a "
1074+
"future Python release. Add a trailing slash to match only "
1075+
"directories and remove this warning.",
1076+
FutureWarning, 3)
10721077
pattern_parts.append('')
10731078

10741079
if case_sensitive is None:

Lib/test/test_pathlib.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -1903,11 +1903,11 @@ def _check(glob, expected):
19031903
"dirC/dirD", "dirC/dirD/fileD"])
19041904
_check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
19051905
_check(p.rglob("**/file*"), ["dirC/fileC", "dirC/dirD/fileD"])
1906-
_check(p.rglob("dir*/**"), ["dirC/dirD"])
1906+
_check(p.rglob("dir*/**/"), ["dirC/dirD"])
19071907
_check(p.rglob("*/*"), ["dirC/dirD/fileD"])
19081908
_check(p.rglob("*/"), ["dirC/dirD"])
19091909
_check(p.rglob(""), ["dirC", "dirC/dirD"])
1910-
_check(p.rglob("**"), ["dirC", "dirC/dirD"])
1910+
_check(p.rglob("**/"), ["dirC", "dirC/dirD"])
19111911
# gh-91616, a re module regression
19121912
_check(p.rglob("*.txt"), ["dirC/novel.txt"])
19131913
_check(p.rglob("*.*"), ["dirC/novel.txt"])
@@ -2057,7 +2057,20 @@ def test_glob_above_recursion_limit(self):
20572057
path.mkdir(parents=True)
20582058

20592059
with set_recursion_limit(recursion_limit):
2060-
list(base.glob('**'))
2060+
list(base.glob('**/'))
2061+
2062+
def test_glob_recursive_no_trailing_slash(self):
2063+
P = self.cls
2064+
p = P(BASE)
2065+
with self.assertWarns(FutureWarning):
2066+
p.glob('**')
2067+
with self.assertWarns(FutureWarning):
2068+
p.glob('*/**')
2069+
with self.assertWarns(FutureWarning):
2070+
p.rglob('**')
2071+
with self.assertWarns(FutureWarning):
2072+
p.rglob('*/**')
2073+
20612074

20622075
def test_readlink(self):
20632076
if not self.can_symlink:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Emit :exc:`FutureWarning` from :meth:`pathlib.Path.glob` and
2+
:meth:`~pathlib.Path.rglob` if the given pattern ends with "``**``". In a
3+
future Python release, patterns with this ending will match both files and
4+
directories. Add a trailing slash to only match directories.

0 commit comments

Comments
 (0)