Skip to content

Commit 206e4c3

Browse files
authored
bpo-38087: Fix case sensitivity in test_pathlib and test_ntpath (GH-15850)
1 parent f12ff05 commit 206e4c3

File tree

3 files changed

+125
-107
lines changed

3 files changed

+125
-107
lines changed

Lib/test/test_ntpath.py

Lines changed: 105 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@
2323
HAVE_GETFINALPATHNAME = True
2424

2525

26+
def _norm(path):
27+
if isinstance(path, (bytes, str, os.PathLike)):
28+
return ntpath.normcase(os.fsdecode(path))
29+
elif hasattr(path, "__iter__"):
30+
return tuple(ntpath.normcase(os.fsdecode(p)) for p in path)
31+
return path
32+
33+
2634
def tester(fn, wantResult):
2735
fn = fn.replace("\\", "\\\\")
2836
gotResult = eval(fn)
29-
if wantResult != gotResult:
37+
if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
3038
raise TestFailed("%s should return: %s but returned: %s" \
3139
%(str(fn), str(wantResult), str(gotResult)))
3240

@@ -42,16 +50,22 @@ def tester(fn, wantResult):
4250
with warnings.catch_warnings():
4351
warnings.simplefilter("ignore", DeprecationWarning)
4452
gotResult = eval(fn)
45-
if isinstance(wantResult, str):
46-
wantResult = os.fsencode(wantResult)
47-
elif isinstance(wantResult, tuple):
48-
wantResult = tuple(os.fsencode(r) for r in wantResult)
49-
if wantResult != gotResult:
53+
if _norm(wantResult) != _norm(gotResult):
5054
raise TestFailed("%s should return: %s but returned: %s" \
5155
%(str(fn), str(wantResult), repr(gotResult)))
5256

5357

54-
class TestNtpath(unittest.TestCase):
58+
class NtpathTestCase(unittest.TestCase):
59+
def assertPathEqual(self, path1, path2):
60+
if path1 == path2 or _norm(path1) == _norm(path2):
61+
return
62+
self.assertEqual(path1, path2)
63+
64+
def assertPathIn(self, path, pathset):
65+
self.assertIn(_norm(path), _norm(pathset))
66+
67+
68+
class TestNtpath(NtpathTestCase):
5569
def test_splitext(self):
5670
tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
5771
tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
@@ -232,8 +246,8 @@ def test_realpath_basic(self):
232246
self.addCleanup(support.unlink, ABSTFN + "1")
233247

234248
os.symlink(ABSTFN, ABSTFN + "1")
235-
self.assertEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
236-
self.assertEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")),
249+
self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
250+
self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")),
237251
os.fsencode(ABSTFN))
238252

239253
@support.skip_unless_symlink
@@ -245,7 +259,7 @@ def test_realpath_relative(self):
245259
self.addCleanup(support.unlink, ABSTFN + "1")
246260

247261
os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1"))
248-
self.assertEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
262+
self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
249263

250264
@support.skip_unless_symlink
251265
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
@@ -268,39 +282,39 @@ def test_realpath_broken_symlinks(self):
268282
os.symlink(ABSTFN + r"\broken", "broken4")
269283
os.symlink(r"recursive\..\broken", "broken5")
270284

271-
self.assertEqual(ntpath.realpath("broken"),
272-
ABSTFN + r"\missing")
273-
self.assertEqual(ntpath.realpath(r"broken\foo"),
274-
ABSTFN + r"\missing\foo")
275-
self.assertEqual(ntpath.realpath(r"broken1"),
276-
ABSTFN + r"\missing\bar")
277-
self.assertEqual(ntpath.realpath(r"broken1\baz"),
278-
ABSTFN + r"\missing\bar\baz")
279-
self.assertEqual(ntpath.realpath("broken2"),
280-
ABSTFN + r"\missing")
281-
self.assertEqual(ntpath.realpath("broken3"),
282-
ABSTFN + r"\missing")
283-
self.assertEqual(ntpath.realpath("broken4"),
284-
ABSTFN + r"\missing")
285-
self.assertEqual(ntpath.realpath("broken5"),
286-
ABSTFN + r"\missing")
287-
288-
self.assertEqual(ntpath.realpath(b"broken"),
289-
os.fsencode(ABSTFN + r"\missing"))
290-
self.assertEqual(ntpath.realpath(rb"broken\foo"),
291-
os.fsencode(ABSTFN + r"\missing\foo"))
292-
self.assertEqual(ntpath.realpath(rb"broken1"),
293-
os.fsencode(ABSTFN + r"\missing\bar"))
294-
self.assertEqual(ntpath.realpath(rb"broken1\baz"),
295-
os.fsencode(ABSTFN + r"\missing\bar\baz"))
296-
self.assertEqual(ntpath.realpath(b"broken2"),
297-
os.fsencode(ABSTFN + r"\missing"))
298-
self.assertEqual(ntpath.realpath(rb"broken3"),
299-
os.fsencode(ABSTFN + r"\missing"))
300-
self.assertEqual(ntpath.realpath(b"broken4"),
301-
os.fsencode(ABSTFN + r"\missing"))
302-
self.assertEqual(ntpath.realpath(b"broken5"),
303-
os.fsencode(ABSTFN + r"\missing"))
285+
self.assertPathEqual(ntpath.realpath("broken"),
286+
ABSTFN + r"\missing")
287+
self.assertPathEqual(ntpath.realpath(r"broken\foo"),
288+
ABSTFN + r"\missing\foo")
289+
self.assertPathEqual(ntpath.realpath(r"broken1"),
290+
ABSTFN + r"\missing\bar")
291+
self.assertPathEqual(ntpath.realpath(r"broken1\baz"),
292+
ABSTFN + r"\missing\bar\baz")
293+
self.assertPathEqual(ntpath.realpath("broken2"),
294+
ABSTFN + r"\missing")
295+
self.assertPathEqual(ntpath.realpath("broken3"),
296+
ABSTFN + r"\missing")
297+
self.assertPathEqual(ntpath.realpath("broken4"),
298+
ABSTFN + r"\missing")
299+
self.assertPathEqual(ntpath.realpath("broken5"),
300+
ABSTFN + r"\missing")
301+
302+
self.assertPathEqual(ntpath.realpath(b"broken"),
303+
os.fsencode(ABSTFN + r"\missing"))
304+
self.assertPathEqual(ntpath.realpath(rb"broken\foo"),
305+
os.fsencode(ABSTFN + r"\missing\foo"))
306+
self.assertPathEqual(ntpath.realpath(rb"broken1"),
307+
os.fsencode(ABSTFN + r"\missing\bar"))
308+
self.assertPathEqual(ntpath.realpath(rb"broken1\baz"),
309+
os.fsencode(ABSTFN + r"\missing\bar\baz"))
310+
self.assertPathEqual(ntpath.realpath(b"broken2"),
311+
os.fsencode(ABSTFN + r"\missing"))
312+
self.assertPathEqual(ntpath.realpath(rb"broken3"),
313+
os.fsencode(ABSTFN + r"\missing"))
314+
self.assertPathEqual(ntpath.realpath(b"broken4"),
315+
os.fsencode(ABSTFN + r"\missing"))
316+
self.assertPathEqual(ntpath.realpath(b"broken5"),
317+
os.fsencode(ABSTFN + r"\missing"))
304318

305319
@support.skip_unless_symlink
306320
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
@@ -318,39 +332,39 @@ def test_realpath_symlink_loops(self):
318332
P = "\\\\?\\"
319333

320334
os.symlink(ABSTFN, ABSTFN)
321-
self.assertEqual(ntpath.realpath(ABSTFN), P + ABSTFN)
335+
self.assertPathEqual(ntpath.realpath(ABSTFN), P + ABSTFN)
322336

323337
# cycles are non-deterministic as to which path is returned, but
324338
# it will always be the fully resolved path of one member of the cycle
325339
os.symlink(ABSTFN + "1", ABSTFN + "2")
326340
os.symlink(ABSTFN + "2", ABSTFN + "1")
327341
expected = (P + ABSTFN + "1", P + ABSTFN + "2")
328-
self.assertIn(ntpath.realpath(ABSTFN + "1"), expected)
329-
self.assertIn(ntpath.realpath(ABSTFN + "2"), expected)
330-
331-
self.assertIn(ntpath.realpath(ABSTFN + "1\\x"),
332-
(ntpath.join(r, "x") for r in expected))
333-
self.assertEqual(ntpath.realpath(ABSTFN + "1\\.."),
334-
ntpath.dirname(ABSTFN))
335-
self.assertEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
336-
ntpath.dirname(ABSTFN) + "\\x")
342+
self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected)
343+
self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected)
344+
345+
self.assertPathIn(ntpath.realpath(ABSTFN + "1\\x"),
346+
(ntpath.join(r, "x") for r in expected))
347+
self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."),
348+
ntpath.dirname(ABSTFN))
349+
self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
350+
ntpath.dirname(ABSTFN) + "\\x")
337351
os.symlink(ABSTFN + "x", ABSTFN + "y")
338-
self.assertEqual(ntpath.realpath(ABSTFN + "1\\..\\"
339-
+ ntpath.basename(ABSTFN) + "y"),
340-
ABSTFN + "x")
341-
self.assertIn(ntpath.realpath(ABSTFN + "1\\..\\"
342-
+ ntpath.basename(ABSTFN) + "1"),
343-
expected)
352+
self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\"
353+
+ ntpath.basename(ABSTFN) + "y"),
354+
ABSTFN + "x")
355+
self.assertPathIn(ntpath.realpath(ABSTFN + "1\\..\\"
356+
+ ntpath.basename(ABSTFN) + "1"),
357+
expected)
344358

345359
os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
346-
self.assertEqual(ntpath.realpath(ABSTFN + "a"), P + ABSTFN + "a")
360+
self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), P + ABSTFN + "a")
347361

348362
os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
349363
+ "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
350-
self.assertEqual(ntpath.realpath(ABSTFN + "c"), P + ABSTFN + "c")
364+
self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), P + ABSTFN + "c")
351365

352366
# Test using relative path as well.
353-
self.assertEqual(ntpath.realpath(ntpath.basename(ABSTFN)), P + ABSTFN)
367+
self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), P + ABSTFN)
354368

355369
@support.skip_unless_symlink
356370
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
@@ -369,10 +383,10 @@ def test_realpath_symlink_prefix(self):
369383
f.write(b'1')
370384
os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link")
371385

372-
self.assertEqual(ntpath.realpath(ABSTFN + "3link"),
373-
ABSTFN + "3")
374-
self.assertEqual(ntpath.realpath(ABSTFN + "3.link"),
375-
"\\\\?\\" + ABSTFN + "3.")
386+
self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"),
387+
ABSTFN + "3")
388+
self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"),
389+
"\\\\?\\" + ABSTFN + "3.")
376390

377391
# Resolved paths should be usable to open target files
378392
with open(ntpath.realpath(ABSTFN + "3link"), "rb") as f:
@@ -381,10 +395,10 @@ def test_realpath_symlink_prefix(self):
381395
self.assertEqual(f.read(), b'1')
382396

383397
# When the prefix is included, it is not stripped
384-
self.assertEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"),
385-
"\\\\?\\" + ABSTFN + "3")
386-
self.assertEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"),
387-
"\\\\?\\" + ABSTFN + "3.")
398+
self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"),
399+
"\\\\?\\" + ABSTFN + "3")
400+
self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"),
401+
"\\\\?\\" + ABSTFN + "3.")
388402

389403
def test_expandvars(self):
390404
with support.EnvironmentVarGuard() as env:
@@ -658,7 +672,7 @@ class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
658672
attributes = ['relpath']
659673

660674

661-
class PathLikeTests(unittest.TestCase):
675+
class PathLikeTests(NtpathTestCase):
662676

663677
path = ntpath
664678

@@ -669,67 +683,67 @@ def setUp(self):
669683
with open(self.file_name, 'xb', 0) as file:
670684
file.write(b"test_ntpath.PathLikeTests")
671685

672-
def assertPathEqual(self, func):
673-
self.assertEqual(func(self.file_path), func(self.file_name))
686+
def _check_function(self, func):
687+
self.assertPathEqual(func(self.file_path), func(self.file_name))
674688

675689
def test_path_normcase(self):
676-
self.assertPathEqual(self.path.normcase)
690+
self._check_function(self.path.normcase)
677691

678692
def test_path_isabs(self):
679-
self.assertPathEqual(self.path.isabs)
693+
self._check_function(self.path.isabs)
680694

681695
def test_path_join(self):
682696
self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
683697
self.path.join('a', 'b', 'c'))
684698

685699
def test_path_split(self):
686-
self.assertPathEqual(self.path.split)
700+
self._check_function(self.path.split)
687701

688702
def test_path_splitext(self):
689-
self.assertPathEqual(self.path.splitext)
703+
self._check_function(self.path.splitext)
690704

691705
def test_path_splitdrive(self):
692-
self.assertPathEqual(self.path.splitdrive)
706+
self._check_function(self.path.splitdrive)
693707

694708
def test_path_basename(self):
695-
self.assertPathEqual(self.path.basename)
709+
self._check_function(self.path.basename)
696710

697711
def test_path_dirname(self):
698-
self.assertPathEqual(self.path.dirname)
712+
self._check_function(self.path.dirname)
699713

700714
def test_path_islink(self):
701-
self.assertPathEqual(self.path.islink)
715+
self._check_function(self.path.islink)
702716

703717
def test_path_lexists(self):
704-
self.assertPathEqual(self.path.lexists)
718+
self._check_function(self.path.lexists)
705719

706720
def test_path_ismount(self):
707-
self.assertPathEqual(self.path.ismount)
721+
self._check_function(self.path.ismount)
708722

709723
def test_path_expanduser(self):
710-
self.assertPathEqual(self.path.expanduser)
724+
self._check_function(self.path.expanduser)
711725

712726
def test_path_expandvars(self):
713-
self.assertPathEqual(self.path.expandvars)
727+
self._check_function(self.path.expandvars)
714728

715729
def test_path_normpath(self):
716-
self.assertPathEqual(self.path.normpath)
730+
self._check_function(self.path.normpath)
717731

718732
def test_path_abspath(self):
719-
self.assertPathEqual(self.path.abspath)
733+
self._check_function(self.path.abspath)
720734

721735
def test_path_realpath(self):
722-
self.assertPathEqual(self.path.realpath)
736+
self._check_function(self.path.realpath)
723737

724738
def test_path_relpath(self):
725-
self.assertPathEqual(self.path.relpath)
739+
self._check_function(self.path.relpath)
726740

727741
def test_path_commonpath(self):
728742
common_path = self.path.commonpath([self.file_path, self.file_name])
729-
self.assertEqual(common_path, self.file_name)
743+
self.assertPathEqual(common_path, self.file_name)
730744

731745
def test_path_isdir(self):
732-
self.assertPathEqual(self.path.isdir)
746+
self._check_function(self.path.isdir)
733747

734748

735749
if __name__ == "__main__":

0 commit comments

Comments
 (0)