Skip to content
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

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

Merged
merged 11 commits into from
May 18, 2023
12 changes: 8 additions & 4 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,22 +680,26 @@ 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):
def match(self, path_pattern, case_sensitive=None):
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved
"""
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
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved
pat = self.with_segments(path_pattern)
if not pat.parts:
raise ValueError("empty pattern")
pat_parts = pat._parts_normcase
parts = self._parts_normcase
pat_parts = str(pat).split(pat._flavour.sep)
parts = str(self).split(self._flavour.sep)
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved
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)):
if not fnmatch.fnmatchcase(part, pat):
match = re.compile(fnmatch.translate(pat), flags).match
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved
if not match(part):
return False
return True

Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,9 @@ 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))
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved

def test_is_absolute(self):
P = self.cls
Expand Down Expand Up @@ -938,6 +941,11 @@ 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))
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved
# 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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added case_sensitive argument to pathlib.PurePath.match()
thirumurugan-git marked this conversation as resolved.
Show resolved Hide resolved