[Python-checkins] bpo-38087: Fix case sensitivity in test_pathlib and test_ntpath (GH-15850)

Zachary Ware webhook-mailer at python.org
Tue Sep 10 09:52:53 EDT 2019


https://github.com/python/cpython/commit/97d7906e30eeee1261b20a45a22242a8accb1cfb
commit: 97d7906e30eeee1261b20a45a22242a8accb1cfb
branch: master
author: Steve Dower <steve.dower at python.org>
committer: Zachary Ware <zachary.ware at gmail.com>
date: 2019-09-10T14:52:48+01:00
summary:

bpo-38087: Fix case sensitivity in test_pathlib and test_ntpath (GH-15850)

files:
A Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst
M Lib/test/test_ntpath.py
M Lib/test/test_pathlib.py

diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index 285fb69dc1e8..c5c96e32d747 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -23,10 +23,18 @@
     HAVE_GETFINALPATHNAME = True
 
 
+def _norm(path):
+    if isinstance(path, (bytes, str, os.PathLike)):
+        return ntpath.normcase(os.fsdecode(path))
+    elif hasattr(path, "__iter__"):
+        return tuple(ntpath.normcase(os.fsdecode(p)) for p in path)
+    return path
+
+
 def tester(fn, wantResult):
     fn = fn.replace("\\", "\\\\")
     gotResult = eval(fn)
-    if wantResult != gotResult:
+    if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
         raise TestFailed("%s should return: %s but returned: %s" \
               %(str(fn), str(wantResult), str(gotResult)))
 
@@ -42,16 +50,22 @@ def tester(fn, wantResult):
     with warnings.catch_warnings():
         warnings.simplefilter("ignore", DeprecationWarning)
         gotResult = eval(fn)
-    if isinstance(wantResult, str):
-        wantResult = os.fsencode(wantResult)
-    elif isinstance(wantResult, tuple):
-        wantResult = tuple(os.fsencode(r) for r in wantResult)
-    if wantResult != gotResult:
+    if _norm(wantResult) != _norm(gotResult):
         raise TestFailed("%s should return: %s but returned: %s" \
               %(str(fn), str(wantResult), repr(gotResult)))
 
 
-class TestNtpath(unittest.TestCase):
+class NtpathTestCase(unittest.TestCase):
+    def assertPathEqual(self, path1, path2):
+        if path1 == path2 or _norm(path1) == _norm(path2):
+            return
+        self.assertEqual(path1, path2)
+
+    def assertPathIn(self, path, pathset):
+        self.assertIn(_norm(path), _norm(pathset))
+
+
+class TestNtpath(NtpathTestCase):
     def test_splitext(self):
         tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
         tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
@@ -232,8 +246,8 @@ def test_realpath_basic(self):
         self.addCleanup(support.unlink, ABSTFN + "1")
 
         os.symlink(ABSTFN, ABSTFN + "1")
-        self.assertEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
-        self.assertEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")),
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
+        self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")),
                          os.fsencode(ABSTFN))
 
     @support.skip_unless_symlink
@@ -245,7 +259,7 @@ def test_realpath_relative(self):
         self.addCleanup(support.unlink, ABSTFN + "1")
 
         os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1"))
-        self.assertEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
 
     @support.skip_unless_symlink
     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
@@ -268,39 +282,39 @@ def test_realpath_broken_symlinks(self):
             os.symlink(ABSTFN + r"\broken", "broken4")
             os.symlink(r"recursive\..\broken", "broken5")
 
-            self.assertEqual(ntpath.realpath("broken"),
-                             ABSTFN + r"\missing")
-            self.assertEqual(ntpath.realpath(r"broken\foo"),
-                             ABSTFN + r"\missing\foo")
-            self.assertEqual(ntpath.realpath(r"broken1"),
-                             ABSTFN + r"\missing\bar")
-            self.assertEqual(ntpath.realpath(r"broken1\baz"),
-                             ABSTFN + r"\missing\bar\baz")
-            self.assertEqual(ntpath.realpath("broken2"),
-                             ABSTFN + r"\missing")
-            self.assertEqual(ntpath.realpath("broken3"),
-                             ABSTFN + r"\missing")
-            self.assertEqual(ntpath.realpath("broken4"),
-                             ABSTFN + r"\missing")
-            self.assertEqual(ntpath.realpath("broken5"),
-                             ABSTFN + r"\missing")
-
-            self.assertEqual(ntpath.realpath(b"broken"),
-                             os.fsencode(ABSTFN + r"\missing"))
-            self.assertEqual(ntpath.realpath(rb"broken\foo"),
-                             os.fsencode(ABSTFN + r"\missing\foo"))
-            self.assertEqual(ntpath.realpath(rb"broken1"),
-                             os.fsencode(ABSTFN + r"\missing\bar"))
-            self.assertEqual(ntpath.realpath(rb"broken1\baz"),
-                             os.fsencode(ABSTFN + r"\missing\bar\baz"))
-            self.assertEqual(ntpath.realpath(b"broken2"),
-                             os.fsencode(ABSTFN + r"\missing"))
-            self.assertEqual(ntpath.realpath(rb"broken3"),
-                             os.fsencode(ABSTFN + r"\missing"))
-            self.assertEqual(ntpath.realpath(b"broken4"),
-                             os.fsencode(ABSTFN + r"\missing"))
-            self.assertEqual(ntpath.realpath(b"broken5"),
-                             os.fsencode(ABSTFN + r"\missing"))
+            self.assertPathEqual(ntpath.realpath("broken"),
+                                 ABSTFN + r"\missing")
+            self.assertPathEqual(ntpath.realpath(r"broken\foo"),
+                                 ABSTFN + r"\missing\foo")
+            self.assertPathEqual(ntpath.realpath(r"broken1"),
+                                 ABSTFN + r"\missing\bar")
+            self.assertPathEqual(ntpath.realpath(r"broken1\baz"),
+                                 ABSTFN + r"\missing\bar\baz")
+            self.assertPathEqual(ntpath.realpath("broken2"),
+                                 ABSTFN + r"\missing")
+            self.assertPathEqual(ntpath.realpath("broken3"),
+                                 ABSTFN + r"\missing")
+            self.assertPathEqual(ntpath.realpath("broken4"),
+                                 ABSTFN + r"\missing")
+            self.assertPathEqual(ntpath.realpath("broken5"),
+                                 ABSTFN + r"\missing")
+
+            self.assertPathEqual(ntpath.realpath(b"broken"),
+                                 os.fsencode(ABSTFN + r"\missing"))
+            self.assertPathEqual(ntpath.realpath(rb"broken\foo"),
+                                 os.fsencode(ABSTFN + r"\missing\foo"))
+            self.assertPathEqual(ntpath.realpath(rb"broken1"),
+                                 os.fsencode(ABSTFN + r"\missing\bar"))
+            self.assertPathEqual(ntpath.realpath(rb"broken1\baz"),
+                                 os.fsencode(ABSTFN + r"\missing\bar\baz"))
+            self.assertPathEqual(ntpath.realpath(b"broken2"),
+                                 os.fsencode(ABSTFN + r"\missing"))
+            self.assertPathEqual(ntpath.realpath(rb"broken3"),
+                                 os.fsencode(ABSTFN + r"\missing"))
+            self.assertPathEqual(ntpath.realpath(b"broken4"),
+                                 os.fsencode(ABSTFN + r"\missing"))
+            self.assertPathEqual(ntpath.realpath(b"broken5"),
+                                 os.fsencode(ABSTFN + r"\missing"))
 
     @support.skip_unless_symlink
     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
@@ -318,39 +332,39 @@ def test_realpath_symlink_loops(self):
         P = "\\\\?\\"
 
         os.symlink(ABSTFN, ABSTFN)
-        self.assertEqual(ntpath.realpath(ABSTFN), P + ABSTFN)
+        self.assertPathEqual(ntpath.realpath(ABSTFN), P + ABSTFN)
 
         # cycles are non-deterministic as to which path is returned, but
         # it will always be the fully resolved path of one member of the cycle
         os.symlink(ABSTFN + "1", ABSTFN + "2")
         os.symlink(ABSTFN + "2", ABSTFN + "1")
         expected = (P + ABSTFN + "1", P + ABSTFN + "2")
-        self.assertIn(ntpath.realpath(ABSTFN + "1"), expected)
-        self.assertIn(ntpath.realpath(ABSTFN + "2"), expected)
-
-        self.assertIn(ntpath.realpath(ABSTFN + "1\\x"),
-                      (ntpath.join(r, "x") for r in expected))
-        self.assertEqual(ntpath.realpath(ABSTFN + "1\\.."),
-                         ntpath.dirname(ABSTFN))
-        self.assertEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
-                         ntpath.dirname(ABSTFN) + "\\x")
+        self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected)
+        self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected)
+
+        self.assertPathIn(ntpath.realpath(ABSTFN + "1\\x"),
+                          (ntpath.join(r, "x") for r in expected))
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."),
+                             ntpath.dirname(ABSTFN))
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
+                             ntpath.dirname(ABSTFN) + "\\x")
         os.symlink(ABSTFN + "x", ABSTFN + "y")
-        self.assertEqual(ntpath.realpath(ABSTFN + "1\\..\\"
-                                         + ntpath.basename(ABSTFN) + "y"),
-                         ABSTFN + "x")
-        self.assertIn(ntpath.realpath(ABSTFN + "1\\..\\"
-                                      + ntpath.basename(ABSTFN) + "1"),
-                      expected)
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\"
+                                             + ntpath.basename(ABSTFN) + "y"),
+                             ABSTFN + "x")
+        self.assertPathIn(ntpath.realpath(ABSTFN + "1\\..\\"
+                                          + ntpath.basename(ABSTFN) + "1"),
+                          expected)
 
         os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
-        self.assertEqual(ntpath.realpath(ABSTFN + "a"), P + ABSTFN + "a")
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), P + ABSTFN + "a")
 
         os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
                    + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
-        self.assertEqual(ntpath.realpath(ABSTFN + "c"), P + ABSTFN + "c")
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), P + ABSTFN + "c")
 
         # Test using relative path as well.
-        self.assertEqual(ntpath.realpath(ntpath.basename(ABSTFN)), P + ABSTFN)
+        self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), P + ABSTFN)
 
     @support.skip_unless_symlink
     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
@@ -369,10 +383,10 @@ def test_realpath_symlink_prefix(self):
             f.write(b'1')
         os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link")
 
-        self.assertEqual(ntpath.realpath(ABSTFN + "3link"),
-                         ABSTFN + "3")
-        self.assertEqual(ntpath.realpath(ABSTFN + "3.link"),
-                         "\\\\?\\" + ABSTFN + "3.")
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"),
+                             ABSTFN + "3")
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"),
+                             "\\\\?\\" + ABSTFN + "3.")
 
         # Resolved paths should be usable to open target files
         with open(ntpath.realpath(ABSTFN + "3link"), "rb") as f:
@@ -381,10 +395,10 @@ def test_realpath_symlink_prefix(self):
             self.assertEqual(f.read(), b'1')
 
         # When the prefix is included, it is not stripped
-        self.assertEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"),
-                         "\\\\?\\" + ABSTFN + "3")
-        self.assertEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"),
-                         "\\\\?\\" + ABSTFN + "3.")
+        self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"),
+                             "\\\\?\\" + ABSTFN + "3")
+        self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"),
+                             "\\\\?\\" + ABSTFN + "3.")
 
     def test_expandvars(self):
         with support.EnvironmentVarGuard() as env:
@@ -658,7 +672,7 @@ class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
     attributes = ['relpath']
 
 
-class PathLikeTests(unittest.TestCase):
+class PathLikeTests(NtpathTestCase):
 
     path = ntpath
 
@@ -669,67 +683,67 @@ def setUp(self):
         with open(self.file_name, 'xb', 0) as file:
             file.write(b"test_ntpath.PathLikeTests")
 
-    def assertPathEqual(self, func):
-        self.assertEqual(func(self.file_path), func(self.file_name))
+    def _check_function(self, func):
+        self.assertPathEqual(func(self.file_path), func(self.file_name))
 
     def test_path_normcase(self):
-        self.assertPathEqual(self.path.normcase)
+        self._check_function(self.path.normcase)
 
     def test_path_isabs(self):
-        self.assertPathEqual(self.path.isabs)
+        self._check_function(self.path.isabs)
 
     def test_path_join(self):
         self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
                          self.path.join('a', 'b', 'c'))
 
     def test_path_split(self):
-        self.assertPathEqual(self.path.split)
+        self._check_function(self.path.split)
 
     def test_path_splitext(self):
-        self.assertPathEqual(self.path.splitext)
+        self._check_function(self.path.splitext)
 
     def test_path_splitdrive(self):
-        self.assertPathEqual(self.path.splitdrive)
+        self._check_function(self.path.splitdrive)
 
     def test_path_basename(self):
-        self.assertPathEqual(self.path.basename)
+        self._check_function(self.path.basename)
 
     def test_path_dirname(self):
-        self.assertPathEqual(self.path.dirname)
+        self._check_function(self.path.dirname)
 
     def test_path_islink(self):
-        self.assertPathEqual(self.path.islink)
+        self._check_function(self.path.islink)
 
     def test_path_lexists(self):
-        self.assertPathEqual(self.path.lexists)
+        self._check_function(self.path.lexists)
 
     def test_path_ismount(self):
-        self.assertPathEqual(self.path.ismount)
+        self._check_function(self.path.ismount)
 
     def test_path_expanduser(self):
-        self.assertPathEqual(self.path.expanduser)
+        self._check_function(self.path.expanduser)
 
     def test_path_expandvars(self):
-        self.assertPathEqual(self.path.expandvars)
+        self._check_function(self.path.expandvars)
 
     def test_path_normpath(self):
-        self.assertPathEqual(self.path.normpath)
+        self._check_function(self.path.normpath)
 
     def test_path_abspath(self):
-        self.assertPathEqual(self.path.abspath)
+        self._check_function(self.path.abspath)
 
     def test_path_realpath(self):
-        self.assertPathEqual(self.path.realpath)
+        self._check_function(self.path.realpath)
 
     def test_path_relpath(self):
-        self.assertPathEqual(self.path.relpath)
+        self._check_function(self.path.relpath)
 
     def test_path_commonpath(self):
         common_path = self.path.commonpath([self.file_path, self.file_name])
-        self.assertEqual(common_path, self.file_name)
+        self.assertPathEqual(common_path, self.file_name)
 
     def test_path_isdir(self):
-        self.assertPathEqual(self.path.isdir)
+        self._check_function(self.path.isdir)
 
 
 if __name__ == "__main__":
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
index cfda0a218826..34c66f3137ff 100644
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1361,10 +1361,13 @@ def assertFileNotFound(self, func, *args, **kwargs):
             func(*args, **kwargs)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
 
+    def assertEqualNormCase(self, path_a, path_b):
+        self.assertEqual(os.path.normcase(path_a), os.path.normcase(path_b))
+
     def _test_cwd(self, p):
         q = self.cls(os.getcwd())
         self.assertEqual(p, q)
-        self.assertEqual(str(p), str(q))
+        self.assertEqualNormCase(str(p), str(q))
         self.assertIs(type(p), type(q))
         self.assertTrue(p.is_absolute())
 
@@ -1375,7 +1378,7 @@ def test_cwd(self):
     def _test_home(self, p):
         q = self.cls(os.path.expanduser('~'))
         self.assertEqual(p, q)
-        self.assertEqual(str(p), str(q))
+        self.assertEqualNormCase(str(p), str(q))
         self.assertIs(type(p), type(q))
         self.assertTrue(p.is_absolute())
 
@@ -1583,14 +1586,14 @@ def test_resolve_common(self):
             p.resolve(strict=True)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         # Non-strict
-        self.assertEqual(str(p.resolve(strict=False)),
-                         os.path.join(BASE, 'foo'))
+        self.assertEqualNormCase(str(p.resolve(strict=False)),
+                                 os.path.join(BASE, 'foo'))
         p = P(BASE, 'foo', 'in', 'spam')
-        self.assertEqual(str(p.resolve(strict=False)),
-                         os.path.join(BASE, 'foo', 'in', 'spam'))
+        self.assertEqualNormCase(str(p.resolve(strict=False)),
+                                 os.path.join(BASE, 'foo', 'in', 'spam'))
         p = P(BASE, '..', 'foo', 'in', 'spam')
-        self.assertEqual(str(p.resolve(strict=False)),
-                         os.path.abspath(os.path.join('foo', 'in', 'spam')))
+        self.assertEqualNormCase(str(p.resolve(strict=False)),
+                                 os.path.abspath(os.path.join('foo', 'in', 'spam')))
         # These are all relative symlinks.
         p = P(BASE, 'dirB', 'fileB')
         self._check_resolve_relative(p, p)
@@ -2137,16 +2140,16 @@ def _check_complex_symlinks(self, link0_target):
         # Resolve absolute paths.
         p = (P / 'link0').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
         p = (P / 'link1').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
         p = (P / 'link2').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
         p = (P / 'link3').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
 
         # Resolve relative paths.
         old_path = os.getcwd()
@@ -2154,16 +2157,16 @@ def _check_complex_symlinks(self, link0_target):
         try:
             p = self.cls('link0').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
             p = self.cls('link1').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
             p = self.cls('link2').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
             p = self.cls('link3').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
         finally:
             os.chdir(old_path)
 
diff --git a/Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst b/Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst
new file mode 100644
index 000000000000..ca625cc775a2
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst
@@ -0,0 +1 @@
+Fix case sensitivity in test_pathlib and test_ntpath.



More information about the Python-checkins mailing list