Visitar URL original
gh-104484: Add parameter @case_sensitive to pathlib.PurePath.match() function by thirumurugan-git · Pull Request #104565 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Code formatting
  • Loading branch information
thirumurugan-git authored and thirumurugan-ka-15679 committed May 17, 2023
commit 1e638fe578484f5dcd9782e601bc2914fe112677
10 changes: 9 additions & 1 deletion Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ Pure paths provide the following methods and properties:
PureWindowsPath('c:/Program Files')


.. method:: PurePath.match(pattern)
.. method:: PurePath.match(pattern, *, case_sensitive=None)

Match this path against the provided glob-style pattern. Return ``True``
if matching is successful, ``False`` otherwise.
Expand Down Expand Up @@ -576,6 +576,14 @@ Pure paths provide the following methods and properties:
>>> PureWindowsPath('b.py').match('*.PY')
True

By default, or when the *case_sensitive* keyword-only argument is set to
Comment thread
thirumurugan-git marked this conversation as resolved.
Outdated
``None``, this method matches paths using platform-specific casing rules:
typically, case-sensitive on POSIX, and case-insensitive on Windows.
Set *case_sensitive* to ``True`` or ``False`` to override this behaviour.
Comment thread
thirumurugan-git marked this conversation as resolved.
Outdated

.. versionadded:: 3.12
The *case_sensitive* argument.


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

Expand Down
14 changes: 10 additions & 4 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ def _make_selector(pattern_parts, flavour, case_sensitive):
return cls(pat, child_parts, flavour, case_sensitive)


@functools.lru_cache(maxsize=256, typed=True)
Comment thread
thirumurugan-git marked this conversation as resolved.
Outdated
def _compile_pattern(pat, flags):
re_pat = fnmatch.translate(pat)
Comment thread
thirumurugan-git marked this conversation as resolved.
Outdated
return re.compile(re_pat, flags).match


class _Selector:
"""A selector matches a specific glob pattern part against the children
of a given path."""
Expand Down Expand Up @@ -680,7 +686,7 @@ def is_reserved(self):
name = self._tail[-1].partition('.')[0].partition(':')[0].rstrip(' ')
return name.upper() in _WIN_RESERVED_NAMES

def match(self, path_pattern, case_sensitive=None):
def match(self, path_pattern, *, case_sensitive=None):
"""
Return True if this path matches the given pattern.
"""
Expand All @@ -690,15 +696,15 @@ def match(self, path_pattern, case_sensitive=None):
pat = self.with_segments(path_pattern)
if not pat.parts:
raise ValueError("empty pattern")
pat_parts = str(pat).split(pat._flavour.sep)
parts = str(self).split(self._flavour.sep)
pat_parts = pat.parts
parts = self.parts
if pat.drive or pat.root:
if len(pat_parts) != len(parts):
return False
elif len(pat_parts) > len(parts):
return False
for part, pat in zip(reversed(parts), reversed(pat_parts)):
match = re.compile(fnmatch.translate(pat), flags).match
match = _compile_pattern(pat, flags)
if not match(part):
return False
return True
Expand Down
13 changes: 5 additions & 8 deletions Lib/test/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ def test_match_common(self):
# Multi-part glob-style pattern.
self.assertFalse(P('/a/b/c.py').match('/**/*.py'))
self.assertTrue(P('/a/b/c.py').match('/a/**/*.py'))
# Case-sensitive flag
self.assertFalse(P('A.py').match('a.PY', case_sensitive=True))
self.assertTrue(P('A.py').match('a.PY', case_sensitive=False))
self.assertFalse(P('c:/a/B.Py').match('C:/A/*.pY', case_sensitive=True))
self.assertTrue(P('/a/b/c.py').match('/A/*/*.Py', case_sensitive=False))
Comment thread
thirumurugan-git marked this conversation as resolved.

def test_ordering_common(self):
# Ordering is tuple-alike.
Expand Down Expand Up @@ -744,9 +749,6 @@ def test_as_uri_non_ascii(self):
def test_match(self):
P = self.cls
self.assertFalse(P('A.py').match('a.PY'))
self.assertTrue(P('A.py').match('a.PY', case_sensitive=False))
self.assertTrue(P('/a/b/c.py').match('/A/*/*.Py', case_sensitive=False))
self.assertTrue(P('/a/b/c.py').match('**/*.py', case_sensitive=False))

def test_is_absolute(self):
P = self.cls
Expand Down Expand Up @@ -941,11 +943,6 @@ def test_match_common(self):
self.assertTrue(P('B.py').match('b.PY'))
self.assertTrue(P('c:/a/B.Py').match('C:/A/*.pY'))
self.assertTrue(P('//Some/Share/B.Py').match('//somE/sharE/*.pY'))
# Case-sensitivity
self.assertFalse(P('A.py').match('a.PY', case_sensitive=True))
self.assertFalse(P('c:/a/B.Py').match('C:/A/*.pY', case_sensitive=True))
self.assertFalse(P('c:/a/B/c.PY').match('C:/A/**/*.pY', case_sensitive=True))
self.assertTrue(P('c:/a/B/c.pY').match('c:/a/**/*.pY', case_sensitive=True))
# Path anchor doesn't match pattern anchor
self.assertFalse(P('c:/b.py').match('/*.py')) # 'c:/' vs '/'
self.assertFalse(P('c:/b.py').match('c:*.py')) # 'c:/' vs 'c:'
Expand Down