8000 Drop 'recursive' argument, make this the only behaviour. · python/cpython@b5c002e · GitHub
[go: up one dir, main page]

Skip to content

Commit b5c002e

Browse files
committed
Drop 'recursive' argument, make this the only behaviour.
1 parent bbd8cd6 commit b5c002e

File tree

3 files changed

+40
-45
lines changed

3 files changed

+40
-45
lines changed

Doc/library/pathlib.rst

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,14 +544,11 @@ Pure paths provide the following methods and properties:
544544
PureWindowsPath('c:/Program Files')
545545

546546

547-
.. method:: PurePath.match(pattern, recursive=False)
547+
.. method:: PurePath.match(pattern)
548548

549549
Match this path against the provided glob-style pattern. Return ``True``
550550
if matching is successful, ``False`` otherwise.
551551

552-
If *recursive* is true, the pattern "``**``" will match any number of file
553-
or directory segments.
554-
555552
If *pattern* is relative, the path can be either relative or absolute,
556553
and matching is done from the right::
557554

@@ -577,8 +574,9 @@ Pure paths provide the following methods and properties:
577574
>>> PureWindowsPath('b.py').match('*.PY')
578575
True
579576

580-
.. versionadded:: 3.12
581-
The *recursive* argument.
577+
.. versionchanged:: 3.12
578+
Support for the recursive wildcard "``**``" was added. In previous
579+
versions, it acted like the non-recursive wildcard "``*``".
582580

583581

584582
.. method:: PurePath.relative_to(other, walk_up=False)

Lib/pathlib.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,25 @@ def _is_wildcard_pattern(pat):
6969

7070

7171
@functools.lru_cache()
72-
def _translate(pattern, recursive):
73-
if recursive:
74-
if pattern == '**\n':
75-
return r'[\S\s]*^'
76-
elif pattern == '**':
77-
return r'[\S\s]*'
78-
elif '**' in pattern:
79-
raise ValueError("Invalid pattern: '**' can only be an entire path component")
80-
return fnmatch._translate(pattern)
72+
def _translate(pattern):
73+
if pattern == '**\n':
74+
return r'[\S\s]*^'
75+
elif pattern == '**':
76+
return r'[\S\s]*'
77+
elif '**' in pattern:
78+
raise ValueError("Invalid pattern: '**' can only be an entire path component")
79+
else:
80+
return fnmatch._translate(pattern)
8181

8282

8383
@functools.lru_cache()
84-
def _make_matcher(path_cls, pattern, recursive):
84+
def _make_matcher(path_cls, pattern):
8585
pattern = path_cls(pattern)
8686
if not pattern._parts:
8787
raise ValueError("empty pattern")
8888
result = [r'\A' if pattern._drv or pattern._root else '^']
8989
for line in pattern._lines_normcase.splitlines(keepends=True):
90-
result.append(_translate(line, recursive))
90+
result.append(_translate(line))
9191
result.append(r'\Z')
9292
return re.compile(''.join(result), flags=re.MULTILINE)
9393

@@ -672,11 +672,11 @@ def _lines_normcase(self):
672672
path = self._flavour.normcase(self.as_posix())
673673
return path.translate(_SWAP_SLASH_AND_NEWLINE)
674674

675-
def match(self, path_pattern, recursive=False):
675+
def match(self, path_pattern):
676676
"""
677677
Return True if this path matches the given pattern.
678678
"""
679-
matcher = _make_matcher(type(self), path_pattern, recursive)
679+
matcher = _make_matcher(type(self), path_pattern)
680680
return matcher.search(self._lines_normcase) is not None
681681

682682

Lib/test/test_pathlib.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -317,33 +317,30 @@ def test_match_common(self):
317317
self.assertFalse(P('/ab.py').match('/a/*.py'))
318318
self.assertFalse(P('/a/b/c.py').match('/a/*.py'))
319319
# Multi-part glob-style pattern.
320-
self.assertFalse(P('/a/b/c.py').match('/**/*.py'))
320+
self.assertTrue(P('a').match('**'))
321+
self.assertTrue(P('c.py').match('**'))
322+
self.assertTrue(P('a/b/c.py').match('**'))
323+
self.assertTrue(P('/a/b/c.py').match('**'))
324+
self.assertTrue(P('/a/b/c.py').match('/**'))
325+
self.assertTrue(P('/a/b/c.py').match('**/'))
326+
self.assertTrue(P('/a/b/c.py').match('/a/**'))
327+
self.assertTrue(P('/a/b/c.py').match('**/*.py'))
328+
self.assertTrue(P('/a/b/c.py').match('/**/*.py'))
321329
self.assertTrue(P('/a/b/c.py').match('/a/**/*.py'))
322-
# Recursive patterns.
323-
self.assertTrue(P('a').match('**', recursive=True))
324-
self.assertTrue(P('c.py').match('**', recursive=True))
325-
self.assertTrue(P('a/b/c.py').match('**', recursive=True))
326-
self.assertTrue(P('/a/b/c.py').match('**', recursive=True))
327-
self.assertTrue(P('/a/b/c.py').match('/**', recursive=True))
328-
self.assertTrue(P('/a/b/c.py').match('**/', recursive=True))
329-
self.assertTrue(P('/a/b/c.py').match('/a/**', recursive=True))
330-
self.assertTrue(P('/a/b/c.py').match('**/*.py', recursive=True))
331-
self.assertTrue(P('/a/b/c.py').match('/**/*.py', recursive=True))
332-
self.assertTrue(P('/a/b/c.py').match('/a/**/*.py', recursive=True))
333-
self.assertTrue(P('/a/b/c.py').match('/a/b/**/*.py', recursive=True))
334-
self.assertTrue(P('/a/b/c.py').match('/**/**/**/**/*.py', recursive=True))
335-
self.assertFalse(P('c.py').match('**/a.py', recursive=True))
336-
self.assertFalse(P('c.py').match('c/**', recursive=True))
337-
self.assertFalse(P('a/b/c.py').match('**/a', recursive=True))
338-
self.assertFalse(P('a/b/c.py').match('**/a/b', recursive=True))
339-
self.assertFalse(P('a/b/c.py').match('**/a/b/c', recursive=True))
340-
self.assertFalse(P('a/b/c.py').match('**/a/b/c.', recursive=True))
341-
self.assertFalse(P('a/b/c.py').match('**/a/b/c./**', recursive=True))
342-
self.assertFalse(P('a/b/c.py').match('**/a/b/c./**', recursive=True))
343-
self.assertFalse(P('a/b/c.py').match('/a/b/c.py/**', recursive=True))
344-
self.assertFalse(P('a/b/c.py').match('/**/a/b/c.py', recursive=True))
345-
self.assertRaises(ValueError, P('a').match, '**a/b/c', recursive=True)
346-
self.assertRaises(ValueError, P('a').match, 'a/b/c**', recursive=True)
330+
self.assertTrue(P('/a/b/c.py').match('/a/b/**/*.py'))
331+
self.assertTrue(P('/a/b/c.py').match('/**/**/**/**/*.py'))
332+
self.assertFalse(P('c.py').match('**/a.py'))
333+
self.assertFalse(P('c.py').match('c/**'))
334+
self.assert 812A False(P('a/b/c.py').match('**/a'))
335+
self.assertFalse(P('a/b/c.py').match('**/a/b'))
336+
self.assertFalse(P('a/b/c.py').match('**/a/b/c'))
337+
self.assertFalse(P('a/b/c.py').match('**/a/b/c.'))
338+
self.assertFalse(P('a/b/c.py').match('**/a/b/c./**'))
339+
self.assertFalse(P('a/b/c.py').match('**/a/b/c./**'))
340+
self.assertFalse(P('a/b/c.py').match('/a/b/c.py/**'))
341+
self.assertFalse(P('a/b/c.py').match('/**/a/b/c.py'))
342+
self.assertRaises(ValueError, P('a').match, '**a/b/c')
343+
self.assertRaises(ValueError, P('a').match, 'a/b/c**')
347344

348345
def test_ordering_common(self):
349346
# Ordering is tuple-alike.

0 commit comments

Comments
 (0)
0