Skip to content
Merged
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):
"""
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")
pat_parts = pat._parts_normcase
parts = self._parts_normcase
pat_parts = str(pat).split(pat._flavour.sep)
parts = str(self).split(self._flavour.sep)
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
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))

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))
# 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()