Skip to content

gh-104484: Add parameter @case_sensitive to pathlib.PurePath.match() function #104565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 18, 2023
Merged
Prev Previous commit
Next Next commit
Resolve threads
  • Loading branch information
thirumurugan-git authored and thirumurugan-ka-15679 committed May 17, 2023
commit 53e0bb8a050d479fbf52608ec0d9de0212c9697d
8 changes: 7 additions & 1 deletion Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,13 @@ Pure paths provide the following methods and properties:

By default, or when the *case_sensitive* keyword-only argument is set to
``None``, this method matches paths using platform-specific casing rules:
typically, case-sensitive on POSIX, and case-insensitive on Windows.
typically, case-sensitive on POSIX, and case-insensitive on Windows::

>>> PurePosixPath('b.py').match('*.PY')
False
>>> PureWindowsPath('b.py').match('*.PY')
True

Set *case_sensitive* to ``True`` or ``False`` to override this behaviour.

.. versionadded:: 3.12
Expand Down
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,9 @@ pathlib
* Add :meth:`pathlib.Path.is_junction` as a proxy to :func:`os.path.isjunction`.
(Contributed by Charles Machalow in :gh:`99547`.)

* Add *case_sensitive* optional parameter to :meth:`pathlib.PurePath.glob`,
:meth:`pathlib.PurePath.rglob` and :meth:`pathlib.PurePath.match` for matching
the path's case sensitivity, allowing for more precise control over the matching process.

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


@functools.lru_cache(maxsize=256, typed=True)
@functools.lru_cache(maxsize=256)
def _compile_pattern(pat, flags):
re_pat = fnmatch.translate(pat)
return re.compile(re_pat, flags).match
return re.compile(fnmatch.translate(pat), flags).match


class _Selector:
Expand Down Expand Up @@ -690,9 +689,6 @@ def match(self, path_pattern, *, case_sensitive=None):
"""
Return True if this path matches the given pattern.
"""
if case_sensitive is None:
case_sensitive = _is_case_sensitive(self._flavour)
flags = re.NOFLAG if case_sensitive else re.IGNORECASE
pat = self.with_segments(path_pattern)
if not pat.parts:
raise ValueError("empty pattern")
Expand All @@ -703,6 +699,11 @@ def match(self, path_pattern, *, case_sensitive=None):
return False
elif len(pat_parts) > len(parts):
return False
# Generate regex flag based on |case_sensitive| parameter.
if case_sensitive is None:
case_sensitive = _is_case_sensitive(self._flavour)
flags = re.NOFLAG if case_sensitive else re.IGNORECASE

for part, pat in zip(reversed(parts), reversed(pat_parts)):
match = _compile_pattern(pat, flags)
if not match(part):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ def test_as_uri(self):
self.assertEqual(P('//some/share/a/b%#c\xe9').as_uri(),
'file://some/share/a/b%25%23c%C3%A9')

def test_match_common(self):
def test_match(self):
P = self.cls
# Absolute patterns.
self.assertTrue(P('c:/b.py').match('*:/*.py'))
Expand Down