summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/pathlib.py5
-rw-r--r--Lib/test/test_ntpath.py4
-rw-r--r--Lib/test/test_pathlib.py9
-rw-r--r--Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst3
4 files changed, 13 insertions, 8 deletions
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
index 17659bc..d7994a3 100644
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -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)):
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index b329006..08c8a7a 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -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")',
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
index a596795..b868379 100644
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -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.
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 0000000..4cfb136
--- /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.