1import ntpath 2import os 3import string 4import sys 5import unittest 6import warnings 7from test.support import os_helper 8from test.support import TestFailed, is_emscripten 9from test.support.os_helper import FakePath 10from test import test_genericpath 11from tempfile import TemporaryFile 12 13 14try: 15 import nt 16except ImportError: 17 # Most tests can complete without the nt module, 18 # but for those that require it we import here. 19 nt = None 20 21try: 22 ntpath._getfinalpathname 23except AttributeError: 24 HAVE_GETFINALPATHNAME = False 25else: 26 HAVE_GETFINALPATHNAME = True 27 28try: 29 import ctypes 30except ImportError: 31 HAVE_GETSHORTPATHNAME = False 32else: 33 HAVE_GETSHORTPATHNAME = True 34 def _getshortpathname(path): 35 GSPN = ctypes.WinDLL("kernel32", use_last_error=True).GetShortPathNameW 36 GSPN.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32] 37 GSPN.restype = ctypes.c_uint32 38 result_len = GSPN(path, None, 0) 39 if not result_len: 40 raise OSError("failed to get short path name 0x{:08X}" 41 .format(ctypes.get_last_error())) 42 result = ctypes.create_unicode_buffer(result_len) 43 result_len = GSPN(path, result, result_len) 44 return result[:result_len] 45 46def _norm(path): 47 if isinstance(path, (bytes, str, os.PathLike)): 48 return ntpath.normcase(os.fsdecode(path)) 49 elif hasattr(path, "__iter__"): 50 return tuple(ntpath.normcase(os.fsdecode(p)) for p in path) 51 return path 52 53 54def tester(fn, wantResult): 55 fn = fn.replace("\\", "\\\\") 56 gotResult = eval(fn) 57 if wantResult != gotResult and _norm(wantResult) != _norm(gotResult): 58 raise TestFailed("%s should return: %s but returned: %s" \ 59 %(str(fn), str(wantResult), str(gotResult))) 60 61 # then with bytes 62 fn = fn.replace("('", "(b'") 63 fn = fn.replace('("', '(b"') 64 fn = fn.replace("['", "[b'") 65 fn = fn.replace('["', '[b"') 66 fn = fn.replace(", '", ", b'") 67 fn = fn.replace(', "', ', b"') 68 fn = os.fsencode(fn).decode('latin1') 69 fn = fn.encode('ascii', 'backslashreplace').decode('ascii') 70 with warnings.catch_warnings(): 71 warnings.simplefilter("ignore", DeprecationWarning) 72 gotResult = eval(fn) 73 if _norm(wantResult) != _norm(gotResult): 74 raise TestFailed("%s should return: %s but returned: %s" \ 75 %(str(fn), str(wantResult), repr(gotResult))) 76 77 78class NtpathTestCase(unittest.TestCase): 79 def assertPathEqual(self, path1, path2): 80 if path1 == path2 or _norm(path1) == _norm(path2): 81 return 82 self.assertEqual(path1, path2) 83 84 def assertPathIn(self, path, pathset): 85 self.assertIn(_norm(path), _norm(pathset)) 86 87 88class TestNtpath(NtpathTestCase): 89 def test_splitext(self): 90 tester('ntpath.splitext("foo.ext")', ('foo', '.ext')) 91 tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext')) 92 tester('ntpath.splitext(".ext")', ('.ext', '')) 93 tester('ntpath.splitext("\\foo.ext\\foo")', ('\\foo.ext\\foo', '')) 94 tester('ntpath.splitext("foo.ext\\")', ('foo.ext\\', '')) 95 tester('ntpath.splitext("")', ('', '')) 96 tester('ntpath.splitext("foo.bar.ext")', ('foo.bar', '.ext')) 97 tester('ntpath.splitext("xx/foo.bar.ext")', ('xx/foo.bar', '.ext')) 98 tester('ntpath.splitext("xx\\foo.bar.ext")', ('xx\\foo.bar', '.ext')) 99 tester('ntpath.splitext("c:a/b\\c.d")', ('c:a/b\\c', '.d')) 100 101 def test_splitdrive(self): 102 tester('ntpath.splitdrive("c:\\foo\\bar")', 103 ('c:', '\\foo\\bar')) 104 tester('ntpath.splitdrive("c:/foo/bar")', 105 ('c:', '/foo/bar')) 106 tester('ntpath.splitdrive("\\\\conky\\mountpoint\\foo\\bar")', 107 ('\\\\conky\\mountpoint', '\\foo\\bar')) 108 tester('ntpath.splitdrive("//conky/mountpoint/foo/bar")', 109 ('//conky/mountpoint', '/foo/bar')) 110 tester('ntpath.splitdrive("\\\\\\conky\\mountpoint\\foo\\bar")', 111 ('\\\\\\conky', '\\mountpoint\\foo\\bar')) 112 tester('ntpath.splitdrive("///conky/mountpoint/foo/bar")', 113 ('///conky', '/mountpoint/foo/bar')) 114 tester('ntpath.splitdrive("\\\\conky\\\\mountpoint\\foo\\bar")', 115 ('\\\\conky\\', '\\mountpoint\\foo\\bar')) 116 tester('ntpath.splitdrive("//conky//mountpoint/foo/bar")', 117 ('//conky/', '/mountpoint/foo/bar')) 118 # Issue #19911: UNC part containing U+0130 119 self.assertEqual(ntpath.splitdrive('//conky/MOUNTPOİNT/foo/bar'), 120 ('//conky/MOUNTPOİNT', '/foo/bar')) 121 122 # gh-81790: support device namespace, including UNC drives. 123 tester('ntpath.splitdrive("//?/c:")', ("//?/c:", "")) 124 tester('ntpath.splitdrive("//?/c:/")', ("//?/c:", "/")) 125 tester('ntpath.splitdrive("//?/c:/dir")', ("//?/c:", "/dir")) 126 tester('ntpath.splitdrive("//?/UNC")', ("//?/UNC", "")) 127 tester('ntpath.splitdrive("//?/UNC/")', ("//?/UNC/", "")) 128 tester('ntpath.splitdrive("//?/UNC/server/")', ("//?/UNC/server/", "")) 129 tester('ntpath.splitdrive("//?/UNC/server/share")', ("//?/UNC/server/share", "")) 130 tester('ntpath.splitdrive("//?/UNC/server/share/dir")', ("//?/UNC/server/share", "/dir")) 131 tester('ntpath.splitdrive("//?/VOLUME{00000000-0000-0000-0000-000000000000}/spam")', 132 ('//?/VOLUME{00000000-0000-0000-0000-000000000000}', '/spam')) 133 tester('ntpath.splitdrive("//?/BootPartition/")', ("//?/BootPartition", "/")) 134 135 tester('ntpath.splitdrive("\\\\?\\c:")', ("\\\\?\\c:", "")) 136 tester('ntpath.splitdrive("\\\\?\\c:\\")', ("\\\\?\\c:", "\\")) 137 tester('ntpath.splitdrive("\\\\?\\c:\\dir")', ("\\\\?\\c:", "\\dir")) 138 tester('ntpath.splitdrive("\\\\?\\UNC")', ("\\\\?\\UNC", "")) 139 tester('ntpath.splitdrive("\\\\?\\UNC\\")', ("\\\\?\\UNC\\", "")) 140 tester('ntpath.splitdrive("\\\\?\\UNC\\server\\")', ("\\\\?\\UNC\\server\\", "")) 141 tester('ntpath.splitdrive("\\\\?\\UNC\\server\\share")', ("\\\\?\\UNC\\server\\share", "")) 142 tester('ntpath.splitdrive("\\\\?\\UNC\\server\\share\\dir")', 143 ("\\\\?\\UNC\\server\\share", "\\dir")) 144 tester('ntpath.splitdrive("\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}\\spam")', 145 ('\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}', '\\spam')) 146 tester('ntpath.splitdrive("\\\\?\\BootPartition\\")', ("\\\\?\\BootPartition", "\\")) 147 148 # gh-96290: support partial/invalid UNC drives 149 tester('ntpath.splitdrive("//")', ("//", "")) # empty server & missing share 150 tester('ntpath.splitdrive("///")', ("///", "")) # empty server & empty share 151 tester('ntpath.splitdrive("///y")', ("///y", "")) # empty server & non-empty share 152 tester('ntpath.splitdrive("//x")', ("//x", "")) # non-empty server & missing share 153 tester('ntpath.splitdrive("//x/")', ("//x/", "")) # non-empty server & empty share 154 155 def test_split(self): 156 tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar')) 157 tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")', 158 ('\\\\conky\\mountpoint\\foo', 'bar')) 159 160 tester('ntpath.split("c:\\")', ('c:\\', '')) 161 tester('ntpath.split("\\\\conky\\mountpoint\\")', 162 ('\\\\conky\\mountpoint\\', '')) 163 164 tester('ntpath.split("c:/")', ('c:/', '')) 165 tester('ntpath.split("//conky/mountpoint/")', ('//conky/mountpoint/', '')) 166 167 def test_isabs(self): 168 tester('ntpath.isabs("c:\\")', 1) 169 tester('ntpath.isabs("\\\\conky\\mountpoint\\")', 1) 170 tester('ntpath.isabs("\\foo")', 1) 171 tester('ntpath.isabs("\\foo\\bar")', 1) 172 173 # gh-96290: normal UNC paths and device paths without trailing backslashes 174 tester('ntpath.isabs("\\\\conky\\mountpoint")', 1) 175 tester('ntpath.isabs("\\\\.\\C:")', 1) 176 177 def test_commonprefix(self): 178 tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])', 179 "/home/swen") 180 tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])', 181 "\\home\\swen\\") 182 tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])', 183 "/home/swen/spam") 184 185 def test_join(self): 186 tester('ntpath.join("")', '') 187 tester('ntpath.join("", "", "")', '') 188 tester('ntpath.join("a")', 'a') 189 tester('ntpath.join("/a")', '/a') 190 tester('ntpath.join("\\a")', '\\a') 191 tester('ntpath.join("a:")', 'a:') 192 tester('ntpath.join("a:", "\\b")', 'a:\\b') 193 tester('ntpath.join("a", "\\b")', '\\b') 194 tester('ntpath.join("a", "b", "c")', 'a\\b\\c') 195 tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c') 196 tester('ntpath.join("a", "b\\", "c")', 'a\\b\\c') 197 tester('ntpath.join("a", "b", "\\c")', '\\c') 198 tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep') 199 tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b') 200 201 tester("ntpath.join('', 'a')", 'a') 202 tester("ntpath.join('', '', '', '', 'a')", 'a') 203 tester("ntpath.join('a', '')", 'a\\') 204 tester("ntpath.join('a', '', '', '', '')", 'a\\') 205 tester("ntpath.join('a\\', '')", 'a\\') 206 tester("ntpath.join('a\\', '', '', '', '')", 'a\\') 207 tester("ntpath.join('a/', '')", 'a/') 208 209 tester("ntpath.join('a/b', 'x/y')", 'a/b\\x/y') 210 tester("ntpath.join('/a/b', 'x/y')", '/a/b\\x/y') 211 tester("ntpath.join('/a/b/', 'x/y')", '/a/b/x/y') 212 tester("ntpath.join('c:', 'x/y')", 'c:x/y') 213 tester("ntpath.join('c:a/b', 'x/y')", 'c:a/b\\x/y') 214 tester("ntpath.join('c:a/b/', 'x/y')", 'c:a/b/x/y') 215 tester("ntpath.join('c:/', 'x/y')", 'c:/x/y') 216 tester("ntpath.join('c:/a/b', 'x/y')", 'c:/a/b\\x/y') 217 tester("ntpath.join('c:/a/b/', 'x/y')", 'c:/a/b/x/y') 218 tester("ntpath.join('//computer/share', 'x/y')", '//computer/share\\x/y') 219 tester("ntpath.join('//computer/share/', 'x/y')", '//computer/share/x/y') 220 tester("ntpath.join('//computer/share/a/b', 'x/y')", '//computer/share/a/b\\x/y') 221 222 tester("ntpath.join('a/b', '/x/y')", '/x/y') 223 tester("ntpath.join('/a/b', '/x/y')", '/x/y') 224 tester("ntpath.join('c:', '/x/y')", 'c:/x/y') 225 tester("ntpath.join('c:a/b', '/x/y')", 'c:/x/y') 226 tester("ntpath.join('c:/', '/x/y')", 'c:/x/y') 227 tester("ntpath.join('c:/a/b', '/x/y')", 'c:/x/y') 228 tester("ntpath.join('//computer/share', '/x/y')", '//computer/share/x/y') 229 tester("ntpath.join('//computer/share/', '/x/y')", '//computer/share/x/y') 230 tester("ntpath.join('//computer/share/a', '/x/y')", '//computer/share/x/y') 231 232 tester("ntpath.join('c:', 'C:x/y')", 'C:x/y') 233 tester("ntpath.join('c:a/b', 'C:x/y')", 'C:a/b\\x/y') 234 tester("ntpath.join('c:/', 'C:x/y')", 'C:/x/y') 235 tester("ntpath.join('c:/a/b', 'C:x/y')", 'C:/a/b\\x/y') 236 237 for x in ('', 'a/b', '/a/b', 'c:', 'c:a/b', 'c:/', 'c:/a/b', 238 '//computer/share', '//computer/share/', '//computer/share/a/b'): 239 for y in ('d:', 'd:x/y', 'd:/', 'd:/x/y', 240 '//machine/common', '//machine/common/', '//machine/common/x/y'): 241 tester("ntpath.join(%r, %r)" % (x, y), y) 242 243 tester("ntpath.join('\\\\computer\\share\\', 'a', 'b')", '\\\\computer\\share\\a\\b') 244 tester("ntpath.join('\\\\computer\\share', 'a', 'b')", '\\\\computer\\share\\a\\b') 245 tester("ntpath.join('\\\\computer\\share', 'a\\b')", '\\\\computer\\share\\a\\b') 246 tester("ntpath.join('//computer/share/', 'a', 'b')", '//computer/share/a\\b') 247 tester("ntpath.join('//computer/share', 'a', 'b')", '//computer/share\\a\\b') 248 tester("ntpath.join('//computer/share', 'a/b')", '//computer/share\\a/b') 249 250 def test_normpath(self): 251 tester("ntpath.normpath('A//////././//.//B')", r'A\B') 252 tester("ntpath.normpath('A/./B')", r'A\B') 253 tester("ntpath.normpath('A/foo/../B')", r'A\B') 254 tester("ntpath.normpath('C:A//B')", r'C:A\B') 255 tester("ntpath.normpath('D:A/./B')", r'D:A\B') 256 tester("ntpath.normpath('e:A/foo/../B')", r'e:A\B') 257 258 tester("ntpath.normpath('C:///A//B')", r'C:\A\B') 259 tester("ntpath.normpath('D:///A/./B')", r'D:\A\B') 260 tester("ntpath.normpath('e:///A/foo/../B')", r'e:\A\B') 261 262 tester("ntpath.normpath('..')", r'..') 263 tester("ntpath.normpath('.')", r'.') 264 tester("ntpath.normpath('')", r'.') 265 tester("ntpath.normpath('/')", '\\') 266 tester("ntpath.normpath('c:/')", 'c:\\') 267 tester("ntpath.normpath('/../.././..')", '\\') 268 tester("ntpath.normpath('c:/../../..')", 'c:\\') 269 tester("ntpath.normpath('../.././..')", r'..\..\..') 270 tester("ntpath.normpath('K:../.././..')", r'K:..\..\..') 271 tester("ntpath.normpath('C:////a/b')", r'C:\a\b') 272 tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b') 273 274 tester("ntpath.normpath('\\\\.\\NUL')", r'\\.\NUL') 275 tester("ntpath.normpath('\\\\?\\D:/XY\\Z')", r'\\?\D:/XY\Z') 276 tester("ntpath.normpath('handbook/../../Tests/image.png')", r'..\Tests\image.png') 277 tester("ntpath.normpath('handbook/../../../Tests/image.png')", r'..\..\Tests\image.png') 278 tester("ntpath.normpath('handbook///../a/.././../b/c')", r'..\b\c') 279 tester("ntpath.normpath('handbook/a/../..///../../b/c')", r'..\..\b\c') 280 281 tester("ntpath.normpath('//server/share/..')" , '\\\\server\\share\\') 282 tester("ntpath.normpath('//server/share/../')" , '\\\\server\\share\\') 283 tester("ntpath.normpath('//server/share/../..')", '\\\\server\\share\\') 284 tester("ntpath.normpath('//server/share/../../')", '\\\\server\\share\\') 285 286 # gh-96290: don't normalize partial/invalid UNC drives as rooted paths. 287 tester("ntpath.normpath('\\\\foo\\\\')", '\\\\foo\\\\') 288 tester("ntpath.normpath('\\\\foo\\')", '\\\\foo\\') 289 tester("ntpath.normpath('\\\\foo')", '\\\\foo') 290 tester("ntpath.normpath('\\\\')", '\\\\') 291 292 def test_realpath_curdir(self): 293 expected = ntpath.normpath(os.getcwd()) 294 tester("ntpath.realpath('.')", expected) 295 tester("ntpath.realpath('./.')", expected) 296 tester("ntpath.realpath('/'.join(['.'] * 100))", expected) 297 tester("ntpath.realpath('.\\.')", expected) 298 tester("ntpath.realpath('\\'.join(['.'] * 100))", expected) 299 300 def test_realpath_pardir(self): 301 expected = ntpath.normpath(os.getcwd()) 302 tester("ntpath.realpath('..')", ntpath.dirname(expected)) 303 tester("ntpath.realpath('../..')", 304 ntpath.dirname(ntpath.dirname(expected))) 305 tester("ntpath.realpath('/'.join(['..'] * 50))", 306 ntpath.splitdrive(expected)[0] + '\\') 307 tester("ntpath.realpath('..\\..')", 308 ntpath.dirname(ntpath.dirname(expected))) 309 tester("ntpath.realpath('\\'.join(['..'] * 50))", 310 ntpath.splitdrive(expected)[0] + '\\') 311 312 @os_helper.skip_unless_symlink 313 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 314 def test_realpath_basic(self): 315 ABSTFN = ntpath.abspath(os_helper.TESTFN) 316 open(ABSTFN, "wb").close() 317 self.addCleanup(os_helper.unlink, ABSTFN) 318 self.addCleanup(os_helper.unlink, ABSTFN + "1") 319 320 os.symlink(ABSTFN, ABSTFN + "1") 321 self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) 322 self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")), 323 os.fsencode(ABSTFN)) 324 325 # gh-88013: call ntpath.realpath with binary drive name may raise a 326 # TypeError. The drive should not exist to reproduce the bug. 327 for c in string.ascii_uppercase: 328 d = f"{c}:\\" 329 if not ntpath.exists(d): 330 break 331 else: 332 raise OSError("No free drive letters available") 333 self.assertEqual(ntpath.realpath(d), d) 334 335 @os_helper.skip_unless_symlink 336 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 337 def test_realpath_strict(self): 338 # Bug #43757: raise FileNotFoundError in strict mode if we encounter 339 # a path that does not exist. 340 ABSTFN = ntpath.abspath(os_helper.TESTFN) 341 os.symlink(ABSTFN + "1", ABSTFN) 342 self.addCleanup(os_helper.unlink, ABSTFN) 343 self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, strict=True) 344 self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", strict=True) 345 346 @os_helper.skip_unless_symlink 347 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 348 def test_realpath_relative(self): 349 ABSTFN = ntpath.abspath(os_helper.TESTFN) 350 open(ABSTFN, "wb").close() 351 self.addCleanup(os_helper.unlink, ABSTFN) 352 self.addCleanup(os_helper.unlink, ABSTFN + "1") 353 354 os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1")) 355 self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) 356 357 @os_helper.skip_unless_symlink 358 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 359 def test_realpath_broken_symlinks(self): 360 ABSTFN = ntpath.abspath(os_helper.TESTFN) 361 os.mkdir(ABSTFN) 362 self.addCleanup(os_helper.rmtree, ABSTFN) 363 364 with os_helper.change_cwd(ABSTFN): 365 os.mkdir("subdir") 366 os.chdir("subdir") 367 os.symlink(".", "recursive") 368 os.symlink("..", "parent") 369 os.chdir("..") 370 os.symlink(".", "self") 371 os.symlink("missing", "broken") 372 os.symlink(r"broken\bar", "broken1") 373 os.symlink(r"self\self\broken", "broken2") 374 os.symlink(r"subdir\parent\subdir\parent\broken", "broken3") 375 os.symlink(ABSTFN + r"\broken", "broken4") 376 os.symlink(r"recursive\..\broken", "broken5") 377 378 self.assertPathEqual(ntpath.realpath("broken"), 379 ABSTFN + r"\missing") 380 self.assertPathEqual(ntpath.realpath(r"broken\foo"), 381 ABSTFN + r"\missing\foo") 382 # bpo-38453: We no longer recursively resolve segments of relative 383 # symlinks that the OS cannot resolve. 384 self.assertPathEqual(ntpath.realpath(r"broken1"), 385 ABSTFN + r"\broken\bar") 386 self.assertPathEqual(ntpath.realpath(r"broken1\baz"), 387 ABSTFN + r"\broken\bar\baz") 388 self.assertPathEqual(ntpath.realpath("broken2"), 389 ABSTFN + r"\self\self\missing") 390 self.assertPathEqual(ntpath.realpath("broken3"), 391 ABSTFN + r"\subdir\parent\subdir\parent\missing") 392 self.assertPathEqual(ntpath.realpath("broken4"), 393 ABSTFN + r"\missing") 394 self.assertPathEqual(ntpath.realpath("broken5"), 395 ABSTFN + r"\missing") 396 397 self.assertPathEqual(ntpath.realpath(b"broken"), 398 os.fsencode(ABSTFN + r"\missing")) 399 self.assertPathEqual(ntpath.realpath(rb"broken\foo"), 400 os.fsencode(ABSTFN + r"\missing\foo")) 401 self.assertPathEqual(ntpath.realpath(rb"broken1"), 402 os.fsencode(ABSTFN + r"\broken\bar")) 403 self.assertPathEqual(ntpath.realpath(rb"broken1\baz"), 404 os.fsencode(ABSTFN + r"\broken\bar\baz")) 405 self.assertPathEqual(ntpath.realpath(b"broken2"), 406 os.fsencode(ABSTFN + r"\self\self\missing")) 407 self.assertPathEqual(ntpath.realpath(rb"broken3"), 408 os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing")) 409 self.assertPathEqual(ntpath.realpath(b"broken4"), 410 os.fsencode(ABSTFN + r"\missing")) 411 self.assertPathEqual(ntpath.realpath(b"broken5"), 412 os.fsencode(ABSTFN + r"\missing")) 413 414 @os_helper.skip_unless_symlink 415 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 416 def test_realpath_symlink_loops(self): 417 # Symlink loops in non-strict mode are non-deterministic as to which 418 # path is returned, but it will always be the fully resolved path of 419 # one member of the cycle 420 ABSTFN = ntpath.abspath(os_helper.TESTFN) 421 self.addCleanup(os_helper.unlink, ABSTFN) 422 self.addCleanup(os_helper.unlink, ABSTFN + "1") 423 self.addCleanup(os_helper.unlink, ABSTFN + "2") 424 self.addCleanup(os_helper.unlink, ABSTFN + "y") 425 self.addCleanup(os_helper.unlink, ABSTFN + "c") 426 self.addCleanup(os_helper.unlink, ABSTFN + "a") 427 428 os.symlink(ABSTFN, ABSTFN) 429 self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN) 430 431 os.symlink(ABSTFN + "1", ABSTFN + "2") 432 os.symlink(ABSTFN + "2", ABSTFN + "1") 433 expected = (ABSTFN + "1", ABSTFN + "2") 434 self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected) 435 self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected) 436 437 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\x"), 438 (ntpath.join(r, "x") for r in expected)) 439 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."), 440 ntpath.dirname(ABSTFN)) 441 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"), 442 ntpath.dirname(ABSTFN) + "\\x") 443 os.symlink(ABSTFN + "x", ABSTFN + "y") 444 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\" 445 + ntpath.basename(ABSTFN) + "y"), 446 ABSTFN + "x") 447 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\..\\" 448 + ntpath.basename(ABSTFN) + "1"), 449 expected) 450 451 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a") 452 self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), ABSTFN + "a") 453 454 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN)) 455 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c") 456 self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), ABSTFN + "c") 457 458 # Test using relative path as well. 459 self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN) 460 461 @os_helper.skip_unless_symlink 462 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 463 def test_realpath_symlink_loops_strict(self): 464 # Symlink loops raise OSError in strict mode 465 ABSTFN = ntpath.abspath(os_helper.TESTFN) 466 self.addCleanup(os_helper.unlink, ABSTFN) 467 self.addCleanup(os_helper.unlink, ABSTFN + "1") 468 self.addCleanup(os_helper.unlink, ABSTFN + "2") 469 self.addCleanup(os_helper.unlink, ABSTFN + "y") 470 self.addCleanup(os_helper.unlink, ABSTFN + "c") 471 self.addCleanup(os_helper.unlink, ABSTFN + "a") 472 473 os.symlink(ABSTFN, ABSTFN) 474 self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=True) 475 476 os.symlink(ABSTFN + "1", ABSTFN + "2") 477 os.symlink(ABSTFN + "2", ABSTFN + "1") 478 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=True) 479 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=True) 480 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", strict=True) 481 # Windows eliminates '..' components before resolving links, so the 482 # following call is not expected to raise. 483 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..", strict=True), 484 ntpath.dirname(ABSTFN)) 485 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\x", strict=True) 486 os.symlink(ABSTFN + "x", ABSTFN + "y") 487 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\" 488 + ntpath.basename(ABSTFN) + "y", 489 strict=True) 490 self.assertRaises(OSError, ntpath.realpath, 491 ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1", 492 strict=True) 493 494 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a") 495 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=True) 496 497 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN)) 498 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c") 499 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=True) 500 501 # Test using relative path as well. 502 self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN), 503 strict=True) 504 505 @os_helper.skip_unless_symlink 506 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 507 def test_realpath_symlink_prefix(self): 508 ABSTFN = ntpath.abspath(os_helper.TESTFN) 509 self.addCleanup(os_helper.unlink, ABSTFN + "3") 510 self.addCleanup(os_helper.unlink, "\\\\?\\" + ABSTFN + "3.") 511 self.addCleanup(os_helper.unlink, ABSTFN + "3link") 512 self.addCleanup(os_helper.unlink, ABSTFN + "3.link") 513 514 with open(ABSTFN + "3", "wb") as f: 515 f.write(b'0') 516 os.symlink(ABSTFN + "3", ABSTFN + "3link") 517 518 with open("\\\\?\\" + ABSTFN + "3.", "wb") as f: 519 f.write(b'1') 520 os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link") 521 522 self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"), 523 ABSTFN + "3") 524 self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"), 525 "\\\\?\\" + ABSTFN + "3.") 526 527 # Resolved paths should be usable to open target files 528 with open(ntpath.realpath(ABSTFN + "3link"), "rb") as f: 529 self.assertEqual(f.read(), b'0') 530 with open(ntpath.realpath(ABSTFN + "3.link"), "rb") as f: 531 self.assertEqual(f.read(), b'1') 532 533 # When the prefix is included, it is not stripped 534 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"), 535 "\\\\?\\" + ABSTFN + "3") 536 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"), 537 "\\\\?\\" + ABSTFN + "3.") 538 539 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 540 def test_realpath_nul(self): 541 tester("ntpath.realpath('NUL')", r'\\.\NUL') 542 543 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 544 @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname') 545 def test_realpath_cwd(self): 546 ABSTFN = ntpath.abspath(os_helper.TESTFN) 547 548 os_helper.unlink(ABSTFN) 549 os_helper.rmtree(ABSTFN) 550 os.mkdir(ABSTFN) 551 self.addCleanup(os_helper.rmtree, ABSTFN) 552 553 test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") 554 os.mkdir(test_dir_long) 555 556 test_dir_short = _getshortpathname(test_dir_long) 557 test_file_long = ntpath.join(test_dir_long, "file.txt") 558 test_file_short = ntpath.join(test_dir_short, "file.txt") 559 560 with open(test_file_long, "wb") as f: 561 f.write(b"content") 562 563 self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short)) 564 565 with os_helper.change_cwd(test_dir_long): 566 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) 567 with os_helper.change_cwd(test_dir_long.lower()): 568 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) 569 with os_helper.change_cwd(test_dir_short): 570 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) 571 572 def test_expandvars(self): 573 with os_helper.EnvironmentVarGuard() as env: 574 env.clear() 575 env["foo"] = "bar" 576 env["{foo"] = "baz1" 577 env["{foo}"] = "baz2" 578 tester('ntpath.expandvars("foo")', "foo") 579 tester('ntpath.expandvars("$foo bar")', "bar bar") 580 tester('ntpath.expandvars("${foo}bar")', "barbar") 581 tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar") 582 tester('ntpath.expandvars("$bar bar")', "$bar bar") 583 tester('ntpath.expandvars("$?bar")', "$?bar") 584 tester('ntpath.expandvars("$foo}bar")', "bar}bar") 585 tester('ntpath.expandvars("${foo")', "${foo") 586 tester('ntpath.expandvars("${{foo}}")', "baz1}") 587 tester('ntpath.expandvars("$foo$foo")', "barbar") 588 tester('ntpath.expandvars("$bar$bar")', "$bar$bar") 589 tester('ntpath.expandvars("%foo% bar")', "bar bar") 590 tester('ntpath.expandvars("%foo%bar")', "barbar") 591 tester('ntpath.expandvars("%foo%%foo%")', "barbar") 592 tester('ntpath.expandvars("%%foo%%foo%foo%")', "%foo%foobar") 593 tester('ntpath.expandvars("%?bar%")', "%?bar%") 594 tester('ntpath.expandvars("%foo%%bar")', "bar%bar") 595 tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar") 596 tester('ntpath.expandvars("bar\'%foo%")', "bar\'%foo%") 597 598 @unittest.skipUnless(os_helper.FS_NONASCII, 'need os_helper.FS_NONASCII') 599 def test_expandvars_nonascii(self): 600 def check(value, expected): 601 tester('ntpath.expandvars(%r)' % value, expected) 602 with os_helper.EnvironmentVarGuard() as env: 603 env.clear() 604 nonascii = os_helper.FS_NONASCII 605 env['spam'] = nonascii 606 env[nonascii] = 'ham' + nonascii 607 check('$spam bar', '%s bar' % nonascii) 608 check('$%s bar' % nonascii, '$%s bar' % nonascii) 609 check('${spam}bar', '%sbar' % nonascii) 610 check('${%s}bar' % nonascii, 'ham%sbar' % nonascii) 611 check('$spam}bar', '%s}bar' % nonascii) 612 check('$%s}bar' % nonascii, '$%s}bar' % nonascii) 613 check('%spam% bar', '%s bar' % nonascii) 614 check('%{}% bar'.format(nonascii), 'ham%s bar' % nonascii) 615 check('%spam%bar', '%sbar' % nonascii) 616 check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii) 617 618 def test_expanduser(self): 619 tester('ntpath.expanduser("test")', 'test') 620 621 with os_helper.EnvironmentVarGuard() as env: 622 env.clear() 623 tester('ntpath.expanduser("~test")', '~test') 624 625 env['HOMEDRIVE'] = 'C:\\' 626 env['HOMEPATH'] = 'Users\\eric' 627 env['USERNAME'] = 'eric' 628 tester('ntpath.expanduser("~test")', 'C:\\Users\\test') 629 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 630 631 del env['HOMEDRIVE'] 632 tester('ntpath.expanduser("~test")', 'Users\\test') 633 tester('ntpath.expanduser("~")', 'Users\\eric') 634 635 env.clear() 636 env['USERPROFILE'] = 'C:\\Users\\eric' 637 env['USERNAME'] = 'eric' 638 tester('ntpath.expanduser("~test")', 'C:\\Users\\test') 639 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 640 tester('ntpath.expanduser("~test\\foo\\bar")', 641 'C:\\Users\\test\\foo\\bar') 642 tester('ntpath.expanduser("~test/foo/bar")', 643 'C:\\Users\\test/foo/bar') 644 tester('ntpath.expanduser("~\\foo\\bar")', 645 'C:\\Users\\eric\\foo\\bar') 646 tester('ntpath.expanduser("~/foo/bar")', 647 'C:\\Users\\eric/foo/bar') 648 649 # bpo-36264: ignore `HOME` when set on windows 650 env.clear() 651 env['HOME'] = 'F:\\' 652 env['USERPROFILE'] = 'C:\\Users\\eric' 653 env['USERNAME'] = 'eric' 654 tester('ntpath.expanduser("~test")', 'C:\\Users\\test') 655 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 656 657 # bpo-39899: don't guess another user's home directory if 658 # `%USERNAME% != basename(%USERPROFILE%)` 659 env.clear() 660 env['USERPROFILE'] = 'C:\\Users\\eric' 661 env['USERNAME'] = 'idle' 662 tester('ntpath.expanduser("~test")', '~test') 663 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 664 665 666 667 @unittest.skipUnless(nt, "abspath requires 'nt' module") 668 def test_abspath(self): 669 tester('ntpath.abspath("C:\\")', "C:\\") 670 tester('ntpath.abspath("\\\\?\\C:////spam////eggs. . .")', "\\\\?\\C:\\spam\\eggs") 671 tester('ntpath.abspath("\\\\.\\C:////spam////eggs. . .")', "\\\\.\\C:\\spam\\eggs") 672 tester('ntpath.abspath("//spam//eggs. . .")', "\\\\spam\\eggs") 673 tester('ntpath.abspath("\\\\spam\\\\eggs. . .")', "\\\\spam\\eggs") 674 tester('ntpath.abspath("C:/spam. . .")', "C:\\spam") 675 tester('ntpath.abspath("C:\\spam. . .")', "C:\\spam") 676 tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") 677 tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") 678 tester('ntpath.abspath("//..")', "\\\\") 679 tester('ntpath.abspath("//../")', "\\\\..\\") 680 tester('ntpath.abspath("//../..")', "\\\\..\\") 681 tester('ntpath.abspath("//../../")', "\\\\..\\..\\") 682 tester('ntpath.abspath("//../../../")', "\\\\..\\..\\") 683 tester('ntpath.abspath("//../../../..")', "\\\\..\\..\\") 684 tester('ntpath.abspath("//../../../../")', "\\\\..\\..\\") 685 tester('ntpath.abspath("//server")', "\\\\server") 686 tester('ntpath.abspath("//server/")', "\\\\server\\") 687 tester('ntpath.abspath("//server/..")', "\\\\server\\") 688 tester('ntpath.abspath("//server/../")', "\\\\server\\..\\") 689 tester('ntpath.abspath("//server/../..")', "\\\\server\\..\\") 690 tester('ntpath.abspath("//server/../../")', "\\\\server\\..\\") 691 tester('ntpath.abspath("//server/../../..")', "\\\\server\\..\\") 692 tester('ntpath.abspath("//server/../../../")', "\\\\server\\..\\") 693 tester('ntpath.abspath("//server/share")', "\\\\server\\share") 694 tester('ntpath.abspath("//server/share/")', "\\\\server\\share\\") 695 tester('ntpath.abspath("//server/share/..")', "\\\\server\\share\\") 696 tester('ntpath.abspath("//server/share/../")', "\\\\server\\share\\") 697 tester('ntpath.abspath("//server/share/../..")', "\\\\server\\share\\") 698 tester('ntpath.abspath("//server/share/../../")', "\\\\server\\share\\") 699 tester('ntpath.abspath("C:\\nul. . .")', "\\\\.\\nul") 700 tester('ntpath.abspath("//... . .")', "\\\\") 701 tester('ntpath.abspath("//.. . . .")', "\\\\") 702 tester('ntpath.abspath("//../... . .")', "\\\\..\\") 703 tester('ntpath.abspath("//../.. . . .")', "\\\\..\\") 704 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047 705 tester('ntpath.abspath("")', cwd_dir) 706 tester('ntpath.abspath(" ")', cwd_dir + "\\ ") 707 tester('ntpath.abspath("?")', cwd_dir + "\\?") 708 drive, _ = ntpath.splitdrive(cwd_dir) 709 tester('ntpath.abspath("/abc/")', drive + "\\abc") 710 711 def test_relpath(self): 712 tester('ntpath.relpath("a")', 'a') 713 tester('ntpath.relpath(ntpath.abspath("a"))', 'a') 714 tester('ntpath.relpath("a/b")', 'a\\b') 715 tester('ntpath.relpath("../a/b")', '..\\a\\b') 716 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: 717 currentdir = ntpath.basename(cwd_dir) 718 tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a') 719 tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b') 720 tester('ntpath.relpath("a", "b/c")', '..\\..\\a') 721 tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat') 722 tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a') 723 tester('ntpath.relpath("a", "a")', '.') 724 tester('ntpath.relpath("/foo/bar/bat", "/x/y/z")', '..\\..\\..\\foo\\bar\\bat') 725 tester('ntpath.relpath("/foo/bar/bat", "/foo/bar")', 'bat') 726 tester('ntpath.relpath("/foo/bar/bat", "/")', 'foo\\bar\\bat') 727 tester('ntpath.relpath("/", "/foo/bar/bat")', '..\\..\\..') 728 tester('ntpath.relpath("/foo/bar/bat", "/x")', '..\\foo\\bar\\bat') 729 tester('ntpath.relpath("/x", "/foo/bar/bat")', '..\\..\\..\\x') 730 tester('ntpath.relpath("/", "/")', '.') 731 tester('ntpath.relpath("/a", "/a")', '.') 732 tester('ntpath.relpath("/a/b", "/a/b")', '.') 733 tester('ntpath.relpath("c:/foo", "C:/FOO")', '.') 734 735 def test_commonpath(self): 736 def check(paths, expected): 737 tester(('ntpath.commonpath(%r)' % paths).replace('\\\\', '\\'), 738 expected) 739 def check_error(exc, paths): 740 self.assertRaises(exc, ntpath.commonpath, paths) 741 self.assertRaises(exc, ntpath.commonpath, 742 [os.fsencode(p) for p in paths]) 743 744 self.assertRaises(ValueError, ntpath.commonpath, []) 745 check_error(ValueError, ['C:\\Program Files', 'Program Files']) 746 check_error(ValueError, ['C:\\Program Files', 'C:Program Files']) 747 check_error(ValueError, ['\\Program Files', 'Program Files']) 748 check_error(ValueError, ['Program Files', 'C:\\Program Files']) 749 check(['C:\\Program Files'], 'C:\\Program Files') 750 check(['C:\\Program Files', 'C:\\Program Files'], 'C:\\Program Files') 751 check(['C:\\Program Files\\', 'C:\\Program Files'], 752 'C:\\Program Files') 753 check(['C:\\Program Files\\', 'C:\\Program Files\\'], 754 'C:\\Program Files') 755 check(['C:\\\\Program Files', 'C:\\Program Files\\\\'], 756 'C:\\Program Files') 757 check(['C:\\.\\Program Files', 'C:\\Program Files\\.'], 758 'C:\\Program Files') 759 check(['C:\\', 'C:\\bin'], 'C:\\') 760 check(['C:\\Program Files', 'C:\\bin'], 'C:\\') 761 check(['C:\\Program Files', 'C:\\Program Files\\Bar'], 762 'C:\\Program Files') 763 check(['C:\\Program Files\\Foo', 'C:\\Program Files\\Bar'], 764 'C:\\Program Files') 765 check(['C:\\Program Files', 'C:\\Projects'], 'C:\\') 766 check(['C:\\Program Files\\', 'C:\\Projects'], 'C:\\') 767 768 check(['C:\\Program Files\\Foo', 'C:/Program Files/Bar'], 769 'C:\\Program Files') 770 check(['C:\\Program Files\\Foo', 'c:/program files/bar'], 771 'C:\\Program Files') 772 check(['c:/program files/bar', 'C:\\Program Files\\Foo'], 773 'c:\\program files') 774 775 check_error(ValueError, ['C:\\Program Files', 'D:\\Program Files']) 776 777 check(['spam'], 'spam') 778 check(['spam', 'spam'], 'spam') 779 check(['spam', 'alot'], '') 780 check(['and\\jam', 'and\\spam'], 'and') 781 check(['and\\\\jam', 'and\\spam\\\\'], 'and') 782 check(['and\\.\\jam', '.\\and\\spam'], 'and') 783 check(['and\\jam', 'and\\spam', 'alot'], '') 784 check(['and\\jam', 'and\\spam', 'and'], 'and') 785 check(['C:and\\jam', 'C:and\\spam'], 'C:and') 786 787 check([''], '') 788 check(['', 'spam\\alot'], '') 789 check_error(ValueError, ['', '\\spam\\alot']) 790 791 self.assertRaises(TypeError, ntpath.commonpath, 792 [b'C:\\Program Files', 'C:\\Program Files\\Foo']) 793 self.assertRaises(TypeError, ntpath.commonpath, 794 [b'C:\\Program Files', 'Program Files\\Foo']) 795 self.assertRaises(TypeError, ntpath.commonpath, 796 [b'Program Files', 'C:\\Program Files\\Foo']) 797 self.assertRaises(TypeError, ntpath.commonpath, 798 ['C:\\Program Files', b'C:\\Program Files\\Foo']) 799 self.assertRaises(TypeError, ntpath.commonpath, 800 ['C:\\Program Files', b'Program Files\\Foo']) 801 self.assertRaises(TypeError, ntpath.commonpath, 802 ['Program Files', b'C:\\Program Files\\Foo']) 803 804 @unittest.skipIf(is_emscripten, "Emscripten cannot fstat unnamed files.") 805 def test_sameopenfile(self): 806 with TemporaryFile() as tf1, TemporaryFile() as tf2: 807 # Make sure the same file is really the same 808 self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno())) 809 # Make sure different files are really different 810 self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno())) 811 # Make sure invalid values don't cause issues on win32 812 if sys.platform == "win32": 813 with self.assertRaises(OSError): 814 # Invalid file descriptors shouldn't display assert 815 # dialogs (#4804) 816 ntpath.sameopenfile(-1, -1) 817 818 def test_ismount(self): 819 self.assertTrue(ntpath.ismount("c:\\")) 820 self.assertTrue(ntpath.ismount("C:\\")) 821 self.assertTrue(ntpath.ismount("c:/")) 822 self.assertTrue(ntpath.ismount("C:/")) 823 self.assertTrue(ntpath.ismount("\\\\.\\c:\\")) 824 self.assertTrue(ntpath.ismount("\\\\.\\C:\\")) 825 826 self.assertTrue(ntpath.ismount(b"c:\\")) 827 self.assertTrue(ntpath.ismount(b"C:\\")) 828 self.assertTrue(ntpath.ismount(b"c:/")) 829 self.assertTrue(ntpath.ismount(b"C:/")) 830 self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\")) 831 self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\")) 832 833 with os_helper.temp_dir() as d: 834 self.assertFalse(ntpath.ismount(d)) 835 836 if sys.platform == "win32": 837 # 838 # Make sure the current folder isn't the root folder 839 # (or any other volume root). The drive-relative 840 # locations below cannot then refer to mount points 841 # 842 test_cwd = os.getenv("SystemRoot") 843 drive, path = ntpath.splitdrive(test_cwd) 844 with os_helper.change_cwd(test_cwd): 845 self.assertFalse(ntpath.ismount(drive.lower())) 846 self.assertFalse(ntpath.ismount(drive.upper())) 847 848 self.assertTrue(ntpath.ismount("\\\\localhost\\c$")) 849 self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\")) 850 851 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$")) 852 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\")) 853 854 def assertEqualCI(self, s1, s2): 855 """Assert that two strings are equal ignoring case differences.""" 856 self.assertEqual(s1.lower(), s2.lower()) 857 858 @unittest.skipUnless(nt, "OS helpers require 'nt' module") 859 def test_nt_helpers(self): 860 # Trivial validation that the helpers do not break, and support both 861 # unicode and bytes (UTF-8) paths 862 863 executable = nt._getfinalpathname(sys.executable) 864 865 for path in executable, os.fsencode(executable): 866 volume_path = nt._getvolumepathname(path) 867 path_drive = ntpath.splitdrive(path)[0] 868 volume_path_drive = ntpath.splitdrive(volume_path)[0] 869 self.assertEqualCI(path_drive, volume_path_drive) 870 871 cap, free = nt._getdiskusage(sys.exec_prefix) 872 self.assertGreater(cap, 0) 873 self.assertGreater(free, 0) 874 b_cap, b_free = nt._getdiskusage(sys.exec_prefix.encode()) 875 # Free space may change, so only test the capacity is equal 876 self.assertEqual(b_cap, cap) 877 self.assertGreater(b_free, 0) 878 879 for path in [sys.prefix, sys.executable]: 880 final_path = nt._getfinalpathname(path) 881 self.assertIsInstance(final_path, str) 882 self.assertGreater(len(final_path), 0) 883 884 b_final_path = nt._getfinalpathname(path.encode()) 885 self.assertIsInstance(b_final_path, bytes) 886 self.assertGreater(len(b_final_path), 0) 887 888class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase): 889 pathmodule = ntpath 890 attributes = ['relpath'] 891 892 893class PathLikeTests(NtpathTestCase): 894 895 path = ntpath 896 897 def setUp(self): 898 self.file_name = os_helper.TESTFN 899 self.file_path = FakePath(os_helper.TESTFN) 900 self.addCleanup(os_helper.unlink, self.file_name) 901 with open(self.file_name, 'xb', 0) as file: 902 file.write(b"test_ntpath.PathLikeTests") 903 904 def _check_function(self, func): 905 self.assertPathEqual(func(self.file_path), func(self.file_name)) 906 907 def test_path_normcase(self): 908 self._check_function(self.path.normcase) 909 if sys.platform == 'win32': 910 self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ') 911 912 def test_path_isabs(self): 913 self._check_function(self.path.isabs) 914 915 def test_path_join(self): 916 self.assertEqual(self.path.join('a', FakePath('b'), 'c'), 917 self.path.join('a', 'b', 'c')) 918 919 def test_path_split(self): 920 self._check_function(self.path.split) 921 922 def test_path_splitext(self): 923 self._check_function(self.path.splitext) 924 925 def test_path_splitdrive(self): 926 self._check_function(self.path.splitdrive) 927 928 def test_path_basename(self): 929 self._check_function(self.path.basename) 930 931 def test_path_dirname(self): 932 self._check_function(self.path.dirname) 933 934 def test_path_islink(self): 935 self._check_function(self.path.islink) 936 937 def test_path_lexists(self): 938 self._check_function(self.path.lexists) 939 940 def test_path_ismount(self): 941 self._check_function(self.path.ismount) 942 943 def test_path_expanduser(self): 944 self._check_function(self.path.expanduser) 945 946 def test_path_expandvars(self): 947 self._check_function(self.path.expandvars) 948 949 def test_path_normpath(self): 950 self._check_function(self.path.normpath) 951 952 def test_path_abspath(self): 953 self._check_function(self.path.abspath) 954 955 def test_path_realpath(self): 956 self._check_function(self.path.realpath) 957 958 def test_path_relpath(self): 959 self._check_function(self.path.relpath) 960 961 def test_path_commonpath(self): 962 common_path = self.path.commonpath([self.file_path, self.file_name]) 963 self.assertPathEqual(common_path, self.file_name) 964 965 def test_path_isdir(self): 966 self._check_function(self.path.isdir) 967 968 969if __name__ == "__main__": 970 unittest.main() 971