Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d401b20

Browse files
authored
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.
1 parent 775f881 commit d401b20

File tree

4 files changed

+13
-8
lines changed

4 files changed

+13
-8
lines changed

Lib/pathlib.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -647,15 +647,10 @@ def match(self, path_pattern):
647647
drv, root, pat_parts = self._parse_parts((path_pattern,))
648648
if not pat_parts:
649649
raise ValueError("empty pattern")
650-
elif drv and drv != self._flavour.normcase(self._drv):
651-
return False
652-
elif root and root != self._root:
653-
return False
654650
parts = self._parts_normcase
655651
if drv or root:
656652
if len(pat_parts) != len(parts):
657653
return False
658-
pat_parts = pat_parts[1:]
659654
elif len(pat_parts) > len(parts):
660655
return False
661656
for part, pat in zip(reversed(parts), reversed(pat_parts)):

Lib/test/test_ntpath.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ def test_splitroot(self):
200200
tester('ntpath.splitroot("//x")', ("//x", "", "")) # non-empty server & missing share
201201
tester('ntpath.splitroot("//x/")', ("//x/", "", "")) # non-empty server & empty share
202202

203+
# gh-101363: match GetFullPathNameW() drive letter parsing behaviour
204+
tester('ntpath.splitroot(" :/foo")', (" :", "/", "foo"))
205+
tester('ntpath.splitroot("/:/foo")', ("", "/", ":/foo"))
206+
203207
def test_split(self):
204208
tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
205209
tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")',

Lib/test/test_pathlib.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,8 +852,7 @@ def test_as_uri(self):
852852
def test_match_common(self):
853853
P = self.cls
854854
# Absolute patterns.
855-
self.assertTrue(P('c:/b.py').match('/*.py'))
856-
self.assertTrue(P('c:/b.py').match('c:*.py'))
855+
self.assertTrue(P('c:/b.py').match('*:/*.py'))
857856
self.assertTrue(P('c:/b.py').match('c:/*.py'))
858857
self.assertFalse(P('d:/b.py').match('c:/*.py')) # wrong drive
859858
self.assertFalse(P('b.py').match('/*.py'))
@@ -864,14 +863,18 @@ def test_match_common(self):
864863
self.assertFalse(P('/b.py').match('c:*.py'))
865864
self.assertFalse(P('/b.py').match('c:/*.py'))
866865
# UNC patterns.
867-
self.assertTrue(P('//some/share/a.py').match('/*.py'))
866+
self.assertTrue(P('//some/share/a.py').match('//*/*/*.py'))
868867
self.assertTrue(P('//some/share/a.py').match('//some/share/*.py'))
869868
self.assertFalse(P('//other/share/a.py').match('//some/share/*.py'))
870869
self.assertFalse(P('//some/share/a/b.py').match('//some/share/*.py'))
871870
# Case-insensitivity.
872871
self.assertTrue(P('B.py').match('b.PY'))
873872
self.assertTrue(P('c:/a/B.Py').match('C:/A/*.pY'))
874873
self.assertTrue(P('//Some/Share/B.Py').match('//somE/sharE/*.pY'))
874+
# Path anchor doesn't match pattern anchor
875+
self.assertFalse(P('c:/b.py').match('/*.py')) # 'c:/' vs '/'
876+
self.assertFalse(P('c:/b.py').match('c:*.py')) # 'c:/' vs 'c:'
877+
self.assertFalse(P('//some/share/a.py').match('/*.py')) # '//some/share/' vs '/'
875878

876879
def test_ordering_common(self):
877880
# Case-insensitivity.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix anchor matching in :meth:`pathlib.PureWindowsPath.match`. Path and
2+
pattern anchors are now matched with :mod:`fnmatch`, just like other path
3+
parts. This allows patterns such as ``"*:/Users/*"`` to be matched.

0 commit comments

Comments
 (0)