diff options
author | Steve Dower <steve.dower@python.org> | 2019-09-10 13:52:48 (GMT) |
---|---|---|
committer | Zachary Ware <zachary.ware@gmail.com> | 2019-09-10 13:52:48 (GMT) |
commit | 97d7906e30eeee1261b20a45a22242a8accb1cfb (patch) | |
tree | 2d94ba32b612a2fbe82b2abd7b42a89d8ef04c28 | |
parent | cd8221152dd235ec5d06e3d9d0d8787645bbac8e (diff) | |
download | cpython-97d7906e30eeee1261b20a45a22242a8accb1cfb.zip cpython-97d7906e30eeee1261b20a45a22242a8accb1cfb.tar.gz cpython-97d7906e30eeee1261b20a45a22242a8accb1cfb.tar.bz2 |
bpo-38087: Fix case sensitivity in test_pathlib and test_ntpath (GH-15850)
-rw-r--r-- | Lib/test/test_ntpath.py | 196 | ||||
-rw-r--r-- | Lib/test/test_pathlib.py | 35 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst | 1 |
3 files changed, 125 insertions, 107 deletions
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 285fb69..c5c96e3 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -23,10 +23,18 @@ else: 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 @@ class TestNtpath(unittest.TestCase): 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 @@ class TestNtpath(unittest.TestCase): 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 @@ class TestNtpath(unittest.TestCase): 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 @@ class TestNtpath(unittest.TestCase): 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 @@ class TestNtpath(unittest.TestCase): 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 @@ class TestNtpath(unittest.TestCase): 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 @@ class PathLikeTests(unittest.TestCase): 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 cfda0a2..34c66f3 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1361,10 +1361,13 @@ class _BasePathTest(object): 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 @@ class _BasePathTest(object): 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 @@ class _BasePathTest(object): 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 @@ class _BasePathTest(object): # 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 @@ class _BasePathTest(object): 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 0000000..ca625cc --- /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. |