From 13e93304f9cdace3f8d33ef05f9afdeef58d9e1b Mon Sep 17 00:00:00 2001 From: barneygale Date: Thu, 26 Jan 2023 23:07:30 +0000 Subject: [PATCH 1/3] gh-101360: Fix anchor matching in pathlib.PureWindowsPath.match() 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. --- Lib/pathlib.py | 5 ----- Lib/test/test_pathlib.py | 9 ++++++--- .../2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst | 3 +++ 3 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst diff --git a/Lib/pathlib.py b/Lib/pathlib.py index ae7a62f8a4cd65..de6ee97ae084dc 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -657,15 +657,10 @@ def match(self, path_pattern): 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)): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 1fe242b7f6ab14..15b4c816f38a97 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -889,8 +889,7 @@ def test_as_uri(self): 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')) @@ -901,7 +900,7 @@ def test_match_common(self): 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')) @@ -909,6 +908,10 @@ 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')) + # 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. diff --git a/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst b/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst new file mode 100644 index 00000000000000..63d1d9e2cda23b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst @@ -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. From f7b879ea229512338255ccb113e68dd88f6a360a Mon Sep 17 00:00:00 2001 From: barneygale Date: Fri, 27 Jan 2023 17:47:14 +0000 Subject: [PATCH 2/3] Fix news blurb syntax --- .../next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst b/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst index 63d1d9e2cda23b..4cfb136c5db853 100644 --- a/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst +++ b/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst @@ -1,3 +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. +parts. This allows patterns such as ``"*:/Users/*"`` to be matched. From 6c0468c895eb6535200b384fa497ea8336c84c78 Mon Sep 17 00:00:00 2001 From: barneygale Date: Sun, 29 Jan 2023 03:05:38 +0000 Subject: [PATCH 3/3] Add splitroot() test cases for slashy and spacey drive letters --- Lib/test/test_ntpath.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index bce38a534a6a98..52922484632d96 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -199,6 +199,10 @@ def test_splitroot(self): 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")',