gh-101360: Fix anchor matching in pathlib.PureWindowsPath.match() (GH-101363)

Use `fnmatch` to match path and pattern anchors, just as we do for other
path parts. This allows patterns such as `'*:/Users/*'` to be matched.
This commit is contained in:
Barney Gale 2023-02-17 14:05:38 +00:00 committed by GitHub
parent 775f8819e3
commit d401b20630
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 8 deletions

View file

@ -647,15 +647,10 @@ class PurePath(object):
drv, root, pat_parts = self._parse_parts((path_pattern,))
if not pat_parts:
raise ValueError("empty pattern")
elif drv and drv != self._flavour.normcase(self._drv):
return False
elif root and root != self._root:
return False
parts = self._parts_normcase
if drv or root:
if len(pat_parts) != len(parts):
return False
pat_parts = pat_parts[1:]
elif len(pat_parts) > len(parts):
return False
for part, pat in zip(reversed(parts), reversed(pat_parts)):

View file

@ -200,6 +200,10 @@ class TestNtpath(NtpathTestCase):
tester('ntpath.splitroot("//x")', ("//x", "", "")) # non-empty server & missing share
tester('ntpath.splitroot("//x/")', ("//x/", "", "")) # non-empty server & empty share
# gh-101363: match GetFullPathNameW() drive letter parsing behaviour
tester('ntpath.splitroot(" :/foo")', (" :", "/", "foo"))
tester('ntpath.splitroot("/:/foo")', ("", "/", ":/foo"))
def test_split(self):
tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")',

View file

@ -852,8 +852,7 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
def test_match_common(self):
P = self.cls
# Absolute patterns.
self.assertTrue(P('c:/b.py').match('/*.py'))
self.assertTrue(P('c:/b.py').match('c:*.py'))
self.assertTrue(P('c:/b.py').match('*:/*.py'))
self.assertTrue(P('c:/b.py').match('c:/*.py'))
self.assertFalse(P('d:/b.py').match('c:/*.py')) # wrong drive
self.assertFalse(P('b.py').match('/*.py'))
@ -864,7 +863,7 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
self.assertFalse(P('/b.py').match('c:*.py'))
self.assertFalse(P('/b.py').match('c:/*.py'))
# UNC patterns.
self.assertTrue(P('//some/share/a.py').match('/*.py'))
self.assertTrue(P('//some/share/a.py').match('//*/*/*.py'))
self.assertTrue(P('//some/share/a.py').match('//some/share/*.py'))
self.assertFalse(P('//other/share/a.py').match('//some/share/*.py'))
self.assertFalse(P('//some/share/a/b.py').match('//some/share/*.py'))
@ -872,6 +871,10 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
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'))
# 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:'
self.assertFalse(P('//some/share/a.py').match('/*.py')) # '//some/share/' vs '/'
def test_ordering_common(self):
# Case-insensitivity.

View file

@ -0,0 +1,3 @@
Fix anchor matching in :meth:`pathlib.PureWindowsPath.match`. Path and
pattern anchors are now matched with :mod:`fnmatch`, just like other path
parts. This allows patterns such as ``"*:/Users/*"`` to be matched.