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 # gh-106242: Embedded nulls and non-strict fallback to abspath 336 self.assertEqual(ABSTFN + "\0spam", 337 ntpath.realpath(os_helper.TESTFN + "\0spam", strict=False)) 338 339 @os_helper.skip_unless_symlink 340 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 341 def test_realpath_strict(self): 342 # Bug #43757: raise FileNotFoundError in strict mode if we encounter 343 # a path that does not exist. 344 ABSTFN = ntpath.abspath(os_helper.TESTFN) 345 os.symlink(ABSTFN + "1", ABSTFN) 346 self.addCleanup(os_helper.unlink, ABSTFN) 347 self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, strict=True) 348 self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", strict=True) 349 # gh-106242: Embedded nulls should raise OSError (not ValueError) 350 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "\0spam", strict=True) 351 352 @os_helper.skip_unless_symlink 353 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 354 def test_realpath_relative(self): 355 ABSTFN = ntpath.abspath(os_helper.TESTFN) 356 open(ABSTFN, "wb").close() 357 self.addCleanup(os_helper.unlink, ABSTFN) 358 self.addCleanup(os_helper.unlink, ABSTFN + "1") 359 360 os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1")) 361 self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) 362 363 @os_helper.skip_unless_symlink 364 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 365 def test_realpath_broken_symlinks(self): 366 ABSTFN = ntpath.abspath(os_helper.TESTFN) 367 os.mkdir(ABSTFN) 368 self.addCleanup(os_helper.rmtree, ABSTFN) 369 370 with os_helper.change_cwd(ABSTFN): 371 os.mkdir("subdir") 372 os.chdir("subdir") 373 os.symlink(".", "recursive") 374 os.symlink("..", "parent") 375 os.chdir("..") 376 os.symlink(".", "self") 377 os.symlink("missing", "broken") 378 os.symlink(r"broken\bar", "broken1") 379 os.symlink(r"self\self\broken", "broken2") 380 os.symlink(r"subdir\parent\subdir\parent\broken", "broken3") 381 os.symlink(ABSTFN + r"\broken", "broken4") 382 os.symlink(r"recursive\..\broken", "broken5") 383 384 self.assertPathEqual(ntpath.realpath("broken"), 385 ABSTFN + r"\missing") 386 self.assertPathEqual(ntpath.realpath(r"broken\foo"), 387 ABSTFN + r"\missing\foo") 388 # bpo-38453: We no longer recursively resolve segments of relative 389 # symlinks that the OS cannot resolve. 390 self.assertPathEqual(ntpath.realpath(r"broken1"), 391 ABSTFN + r"\broken\bar") 392 self.assertPathEqual(ntpath.realpath(r"broken1\baz"), 393 ABSTFN + r"\broken\bar\baz") 394 self.assertPathEqual(ntpath.realpath("broken2"), 395 ABSTFN + r"\self\self\missing") 396 self.assertPathEqual(ntpath.realpath("broken3"), 397 ABSTFN + r"\subdir\parent\subdir\parent\missing") 398 self.assertPathEqual(ntpath.realpath("broken4"), 399 ABSTFN + r"\missing") 400 self.assertPathEqual(ntpath.realpath("broken5"), 401 ABSTFN + r"\missing") 402 403 self.assertPathEqual(ntpath.realpath(b"broken"), 404 os.fsencode(ABSTFN + r"\missing")) 405 self.assertPathEqual(ntpath.realpath(rb"broken\foo"), 406 os.fsencode(ABSTFN + r"\missing\foo")) 407 self.assertPathEqual(ntpath.realpath(rb"broken1"), 408 os.fsencode(ABSTFN + r"\broken\bar")) 409 self.assertPathEqual(ntpath.realpath(rb"broken1\baz"), 410 os.fsencode(ABSTFN + r"\broken\bar\baz")) 411 self.assertPathEqual(ntpath.realpath(b"broken2"), 412 os.fsencode(ABSTFN + r"\self\self\missing")) 413 self.assertPathEqual(ntpath.realpath(rb"broken3"), 414 os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing")) 415 self.assertPathEqual(ntpath.realpath(b"broken4"), 416 os.fsencode(ABSTFN + r"\missing")) 417 self.assertPathEqual(ntpath.realpath(b"broken5"), 418 os.fsencode(ABSTFN + r"\missing")) 419 420 @os_helper.skip_unless_symlink 421 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 422 def test_realpath_symlink_loops(self): 423 # Symlink loops in non-strict mode are non-deterministic as to which 424 # path is returned, but it will always be the fully resolved path of 425 # one member of the cycle 426 ABSTFN = ntpath.abspath(os_helper.TESTFN) 427 self.addCleanup(os_helper.unlink, ABSTFN) 428 self.addCleanup(os_helper.unlink, ABSTFN + "1") 429 self.addCleanup(os_helper.unlink, ABSTFN + "2") 430 self.addCleanup(os_helper.unlink, ABSTFN + "y") 431 self.addCleanup(os_helper.unlink, ABSTFN + "c") 432 self.addCleanup(os_helper.unlink, ABSTFN + "a") 433 434 os.symlink(ABSTFN, ABSTFN) 435 self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN) 436 437 os.symlink(ABSTFN + "1", ABSTFN + "2") 438 os.symlink(ABSTFN + "2", ABSTFN + "1") 439 expected = (ABSTFN + "1", ABSTFN + "2") 440 self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected) 441 self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected) 442 443 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\x"), 444 (ntpath.join(r, "x") for r in expected)) 445 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."), 446 ntpath.dirname(ABSTFN)) 447 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"), 448 ntpath.dirname(ABSTFN) + "\\x") 449 os.symlink(ABSTFN + "x", ABSTFN + "y") 450 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\" 451 + ntpath.basename(ABSTFN) + "y"), 452 ABSTFN + "x") 453 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\..\\" 454 + ntpath.basename(ABSTFN) + "1"), 455 expected) 456 457 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a") 458 self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), ABSTFN + "a") 459 460 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN)) 461 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c") 462 self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), ABSTFN + "c") 463 464 # Test using relative path as well. 465 self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN) 466 467 @os_helper.skip_unless_symlink 468 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 469 def test_realpath_symlink_loops_strict(self): 470 # Symlink loops raise OSError in strict mode 471 ABSTFN = ntpath.abspath(os_helper.TESTFN) 472 self.addCleanup(os_helper.unlink, ABSTFN) 473 self.addCleanup(os_helper.unlink, ABSTFN + "1") 474 self.addCleanup(os_helper.unlink, ABSTFN + "2") 475 self.addCleanup(os_helper.unlink, ABSTFN + "y") 476 self.addCleanup(os_helper.unlink, ABSTFN + "c") 477 self.addCleanup(os_helper.unlink, ABSTFN + "a") 478 479 os.symlink(ABSTFN, ABSTFN) 480 self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=True) 481 482 os.symlink(ABSTFN + "1", ABSTFN + "2") 483 os.symlink(ABSTFN + "2", ABSTFN + "1") 484 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=True) 485 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=True) 486 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", strict=True) 487 # Windows eliminates '..' components before resolving links, so the 488 # following call is not expected to raise. 489 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..", strict=True), 490 ntpath.dirname(ABSTFN)) 491 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\x", strict=True) 492 os.symlink(ABSTFN + "x", ABSTFN + "y") 493 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\" 494 + ntpath.basename(ABSTFN) + "y", 495 strict=True) 496 self.assertRaises(OSError, ntpath.realpath, 497 ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1", 498 strict=True) 499 500 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a") 501 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=True) 502 503 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN)) 504 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c") 505 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=True) 506 507 # Test using relative path as well. 508 self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN), 509 strict=True) 510 511 @os_helper.skip_unless_symlink 512 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 513 def test_realpath_symlink_prefix(self): 514 ABSTFN = ntpath.abspath(os_helper.TESTFN) 515 self.addCleanup(os_helper.unlink, ABSTFN + "3") 516 self.addCleanup(os_helper.unlink, "\\\\?\\" + ABSTFN + "3.") 517 self.addCleanup(os_helper.unlink, ABSTFN + "3link") 518 self.addCleanup(os_helper.unlink, ABSTFN + "3.link") 519 520 with open(ABSTFN + "3", "wb") as f: 521 f.write(b'0') 522 os.symlink(ABSTFN + "3", ABSTFN + "3link") 523 524 with open("\\\\?\\" + ABSTFN + "3.", "wb") as f: 525 f.write(b'1') 526 os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link") 527 528 self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"), 529 ABSTFN + "3") 530 self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"), 531 "\\\\?\\" + ABSTFN + "3.") 532 533 # Resolved paths should be usable to open target files 534 with open(ntpath.realpath(ABSTFN + "3link"), "rb") as f: 535 self.assertEqual(f.read(), b'0') 536 with open(ntpath.realpath(ABSTFN + "3.link"), "rb") as f: 537 self.assertEqual(f.read(), b'1') 538 539 # When the prefix is included, it is not stripped 540 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"), 541 "\\\\?\\" + ABSTFN + "3") 542 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"), 543 "\\\\?\\" + ABSTFN + "3.") 544 545 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 546 def test_realpath_nul(self): 547 tester("ntpath.realpath('NUL')", r'\\.\NUL') 548 549 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') 550 @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname') 551 def test_realpath_cwd(self): 552 ABSTFN = ntpath.abspath(os_helper.TESTFN) 553 554 os_helper.unlink(ABSTFN) 555 os_helper.rmtree(ABSTFN) 556 os.mkdir(ABSTFN) 557 self.addCleanup(os_helper.rmtree, ABSTFN) 558 559 test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") 560 os.mkdir(test_dir_long) 561 562 test_dir_short = _getshortpathname(test_dir_long) 563 test_file_long = ntpath.join(test_dir_long, "file.txt") 564 test_file_short = ntpath.join(test_dir_short, "file.txt") 565 566 with open(test_file_long, "wb") as f: 567 f.write(b"content") 568 569 self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short)) 570 571 with os_helper.change_cwd(test_dir_long): 572 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) 573 with os_helper.change_cwd(test_dir_long.lower()): 574 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) 575 with os_helper.change_cwd(test_dir_short): 576 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) 577 578 def test_expandvars(self): 579 with os_helper.EnvironmentVarGuard() as env: 580 env.clear() 581 env["foo"] = "bar" 582 env["{foo"] = "baz1" 583 env["{foo}"] = "baz2" 584 tester('ntpath.expandvars("foo")', "foo") 585 tester('ntpath.expandvars("$foo bar")', "bar bar") 586 tester('ntpath.expandvars("${foo}bar")', "barbar") 587 tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar") 588 tester('ntpath.expandvars("$bar bar")', "$bar bar") 589 tester('ntpath.expandvars("$?bar")', "$?bar") 590 tester('ntpath.expandvars("$foo}bar")', "bar}bar") 591 tester('ntpath.expandvars("${foo")', "${foo") 592 tester('ntpath.expandvars("${{foo}}")', "baz1}") 593 tester('ntpath.expandvars("$foo$foo")', "barbar") 594 tester('ntpath.expandvars("$bar$bar")', "$bar$bar") 595 tester('ntpath.expandvars("%foo% bar")', "bar bar") 596 tester('ntpath.expandvars("%foo%bar")', "barbar") 597 tester('ntpath.expandvars("%foo%%foo%")', "barbar") 598 tester('ntpath.expandvars("%%foo%%foo%foo%")', "%foo%foobar") 599 tester('ntpath.expandvars("%?bar%")', "%?bar%") 600 tester('ntpath.expandvars("%foo%%bar")', "bar%bar") 601 tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar") 602 tester('ntpath.expandvars("bar\'%foo%")', "bar\'%foo%") 603 604 @unittest.skipUnless(os_helper.FS_NONASCII, 'need os_helper.FS_NONASCII') 605 def test_expandvars_nonascii(self): 606 def check(value, expected): 607 tester('ntpath.expandvars(%r)' % value, expected) 608 with os_helper.EnvironmentVarGuard() as env: 609 env.clear() 610 nonascii = os_helper.FS_NONASCII 611 env['spam'] = nonascii 612 env[nonascii] = 'ham' + nonascii 613 check('$spam bar', '%s bar' % nonascii) 614 check('$%s bar' % nonascii, '$%s bar' % nonascii) 615 check('${spam}bar', '%sbar' % nonascii) 616 check('${%s}bar' % nonascii, 'ham%sbar' % nonascii) 617 check('$spam}bar', '%s}bar' % nonascii) 618 check('$%s}bar' % nonascii, '$%s}bar' % nonascii) 619 check('%spam% bar', '%s bar' % nonascii) 620 check('%{}% bar'.format(nonascii), 'ham%s bar' % nonascii) 621 check('%spam%bar', '%sbar' % nonascii) 622 check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii) 623 624 def test_expanduser(self): 625 tester('ntpath.expanduser("test")', 'test') 626 627 with os_helper.EnvironmentVarGuard() as env: 628 env.clear() 629 tester('ntpath.expanduser("~test")', '~test') 630 631 env['HOMEDRIVE'] = 'C:\\' 632 env['HOMEPATH'] = 'Users\\eric' 633 env['USERNAME'] = 'eric' 634 tester('ntpath.expanduser("~test")', 'C:\\Users\\test') 635 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 636 637 del env['HOMEDRIVE'] 638 tester('ntpath.expanduser("~test")', 'Users\\test') 639 tester('ntpath.expanduser("~")', 'Users\\eric') 640 641 env.clear() 642 env['USERPROFILE'] = 'C:\\Users\\eric' 643 env['USERNAME'] = 'eric' 644 tester('ntpath.expanduser("~test")', 'C:\\Users\\test') 645 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 646 tester('ntpath.expanduser("~test\\foo\\bar")', 647 'C:\\Users\\test\\foo\\bar') 648 tester('ntpath.expanduser("~test/foo/bar")', 649 'C:\\Users\\test/foo/bar') 650 tester('ntpath.expanduser("~\\foo\\bar")', 651 'C:\\Users\\eric\\foo\\bar') 652 tester('ntpath.expanduser("~/foo/bar")', 653 'C:\\Users\\eric/foo/bar') 654 655 # bpo-36264: ignore `HOME` when set on windows 656 env.clear() 657 env['HOME'] = 'F:\\' 658 env['USERPROFILE'] = 'C:\\Users\\eric' 659 env['USERNAME'] = 'eric' 660 tester('ntpath.expanduser("~test")', 'C:\\Users\\test') 661 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 662 663 # bpo-39899: don't guess another user's home directory if 664 # `%USERNAME% != basename(%USERPROFILE%)` 665 env.clear() 666 env['USERPROFILE'] = 'C:\\Users\\eric' 667 env['USERNAME'] = 'idle' 668 tester('ntpath.expanduser("~test")', '~test') 669 tester('ntpath.expanduser("~")', 'C:\\Users\\eric') 670 671 672 673 @unittest.skipUnless(nt, "abspath requires 'nt' module") 674 def test_abspath(self): 675 tester('ntpath.abspath("C:\\")', "C:\\") 676 tester('ntpath.abspath("\\\\?\\C:////spam////eggs. . .")', "\\\\?\\C:\\spam\\eggs") 677 tester('ntpath.abspath("\\\\.\\C:////spam////eggs. . .")', "\\\\.\\C:\\spam\\eggs") 678 tester('ntpath.abspath("//spam//eggs. . .")', "\\\\spam\\eggs") 679 tester('ntpath.abspath("\\\\spam\\\\eggs. . .")', "\\\\spam\\eggs") 680 tester('ntpath.abspath("C:/spam. . .")', "C:\\spam") 681 tester('ntpath.abspath("C:\\spam. . .")', "C:\\spam") 682 tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") 683 tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") 684 tester('ntpath.abspath("//..")', "\\\\") 685 tester('ntpath.abspath("//../")', "\\\\..\\") 686 tester('ntpath.abspath("//../..")', "\\\\..\\") 687 tester('ntpath.abspath("//../../")', "\\\\..\\..\\") 688 tester('ntpath.abspath("//../../../")', "\\\\..\\..\\") 689 tester('ntpath.abspath("//../../../..")', "\\\\..\\..\\") 690 tester('ntpath.abspath("//../../../../")', "\\\\..\\..\\") 691 tester('ntpath.abspath("//server")', "\\\\server") 692 tester('ntpath.abspath("//server/")', "\\\\server\\") 693 tester('ntpath.abspath("//server/..")', "\\\\server\\") 694 tester('ntpath.abspath("//server/../")', "\\\\server\\..\\") 695 tester('ntpath.abspath("//server/../..")', "\\\\server\\..\\") 696 tester('ntpath.abspath("//server/../../")', "\\\\server\\..\\") 697 tester('ntpath.abspath("//server/../../..")', "\\\\server\\..\\") 698 tester('ntpath.abspath("//server/../../../")', "\\\\server\\..\\") 699 tester('ntpath.abspath("//server/share")', "\\\\server\\share") 700 tester('ntpath.abspath("//server/share/")', "\\\\server\\share\\") 701 tester('ntpath.abspath("//server/share/..")', "\\\\server\\share\\") 702 tester('ntpath.abspath("//server/share/../")', "\\\\server\\share\\") 703 tester('ntpath.abspath("//server/share/../..")', "\\\\server\\share\\") 704 tester('ntpath.abspath("//server/share/../../")', "\\\\server\\share\\") 705 tester('ntpath.abspath("C:\\nul. . .")', "\\\\.\\nul") 706 tester('ntpath.abspath("//... . .")', "\\\\") 707 tester('ntpath.abspath("//.. . . .")', "\\\\") 708 tester('ntpath.abspath("//../... . .")', "\\\\..\\") 709 tester('ntpath.abspath("//../.. . . .")', "\\\\..\\") 710 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047 711 tester('ntpath.abspath("")', cwd_dir) 712 tester('ntpath.abspath(" ")', cwd_dir + "\\ ") 713 tester('ntpath.abspath("?")', cwd_dir + "\\?") 714 drive, _ = ntpath.splitdrive(cwd_dir) 715 tester('ntpath.abspath("/abc/")', drive + "\\abc") 716 717 def test_relpath(self): 718 tester('ntpath.relpath("a")', 'a') 719 tester('ntpath.relpath(ntpath.abspath("a"))', 'a') 720 tester('ntpath.relpath("a/b")', 'a\\b') 721 tester('ntpath.relpath("../a/b")', '..\\a\\b') 722 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: 723 currentdir = ntpath.basename(cwd_dir) 724 tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a') 725 tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b') 726 tester('ntpath.relpath("a", "b/c")', '..\\..\\a') 727 tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat') 728 tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a') 729 tester('ntpath.relpath("a", "a")', '.') 730 tester('ntpath.relpath("/foo/bar/bat", "/x/y/z")', '..\\..\\..\\foo\\bar\\bat') 731 tester('ntpath.relpath("/foo/bar/bat", "/foo/bar")', 'bat') 732 tester('ntpath.relpath("/foo/bar/bat", "/")', 'foo\\bar\\bat') 733 tester('ntpath.relpath("/", "/foo/bar/bat")', '..\\..\\..') 734 tester('ntpath.relpath("/foo/bar/bat", "/x")', '..\\foo\\bar\\bat') 735 tester('ntpath.relpath("/x", "/foo/bar/bat")', '..\\..\\..\\x') 736 tester('ntpath.relpath("/", "/")', '.') 737 tester('ntpath.relpath("/a", "/a")', '.') 738 tester('ntpath.relpath("/a/b", "/a/b")', '.') 739 tester('ntpath.relpath("c:/foo", "C:/FOO")', '.') 740 741 def test_commonpath(self): 742 def check(paths, expected): 743 tester(('ntpath.commonpath(%r)' % paths).replace('\\\\', '\\'), 744 expected) 745 def check_error(exc, paths): 746 self.assertRaises(exc, ntpath.commonpath, paths) 747 self.assertRaises(exc, ntpath.commonpath, 748 [os.fsencode(p) for p in paths]) 749 750 self.assertRaises(ValueError, ntpath.commonpath, []) 751 check_error(ValueError, ['C:\\Program Files', 'Program Files']) 752 check_error(ValueError, ['C:\\Program Files', 'C:Program Files']) 753 check_error(ValueError, ['\\Program Files', 'Program Files']) 754 check_error(ValueError, ['Program Files', 'C:\\Program Files']) 755 check(['C:\\Program Files'], 'C:\\Program Files') 756 check(['C:\\Program Files', 'C:\\Program Files'], 'C:\\Program Files') 757 check(['C:\\Program Files\\', 'C:\\Program Files'], 758 'C:\\Program Files') 759 check(['C:\\Program Files\\', 'C:\\Program Files\\'], 760 'C:\\Program Files') 761 check(['C:\\\\Program Files', 'C:\\Program Files\\\\'], 762 'C:\\Program Files') 763 check(['C:\\.\\Program Files', 'C:\\Program Files\\.'], 764 'C:\\Program Files') 765 check(['C:\\', 'C:\\bin'], 'C:\\') 766 check(['C:\\Program Files', 'C:\\bin'], 'C:\\') 767 check(['C:\\Program Files', 'C:\\Program Files\\Bar'], 768 'C:\\Program Files') 769 check(['C:\\Program Files\\Foo', 'C:\\Program Files\\Bar'], 770 'C:\\Program Files') 771 check(['C:\\Program Files', 'C:\\Projects'], 'C:\\') 772 check(['C:\\Program Files\\', 'C:\\Projects'], 'C:\\') 773 774 check(['C:\\Program Files\\Foo', 'C:/Program Files/Bar'], 775 'C:\\Program Files') 776 check(['C:\\Program Files\\Foo', 'c:/program files/bar'], 777 'C:\\Program Files') 778 check(['c:/program files/bar', 'C:\\Program Files\\Foo'], 779 'c:\\program files') 780 781 check_error(ValueError, ['C:\\Program Files', 'D:\\Program Files']) 782 783 check(['spam'], 'spam') 784 check(['spam', 'spam'], 'spam') 785 check(['spam', 'alot'], '') 786 check(['and\\jam', 'and\\spam'], 'and') 787 check(['and\\\\jam', 'and\\spam\\\\'], 'and') 788 check(['and\\.\\jam', '.\\and\\spam'], 'and') 789 check(['and\\jam', 'and\\spam', 'alot'], '') 790 check(['and\\jam', 'and\\spam', 'and'], 'and') 791 check(['C:and\\jam', 'C:and\\spam'], 'C:and') 792 793 check([''], '') 794 check(['', 'spam\\alot'], '') 795 check_error(ValueError, ['', '\\spam\\alot']) 796 797 self.assertRaises(TypeError, ntpath.commonpath, 798 [b'C:\\Program Files', 'C:\\Program Files\\Foo']) 799 self.assertRaises(TypeError, ntpath.commonpath, 800 [b'C:\\Program Files', 'Program Files\\Foo']) 801 self.assertRaises(TypeError, ntpath.commonpath, 802 [b'Program Files', 'C:\\Program Files\\Foo']) 803 self.assertRaises(TypeError, ntpath.commonpath, 804 ['C:\\Program Files', b'C:\\Program Files\\Foo']) 805 self.assertRaises(TypeError, ntpath.commonpath, 806 ['C:\\Program Files', b'Program Files\\Foo']) 807 self.assertRaises(TypeError, ntpath.commonpath, 808 ['Program Files', b'C:\\Program Files\\Foo']) 809 810 @unittest.skipIf(is_emscripten, "Emscripten cannot fstat unnamed files.") 811 def test_sameopenfile(self): 812 with TemporaryFile() as tf1, TemporaryFile() as tf2: 813 # Make sure the same file is really the same 814 self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno())) 815 # Make sure different files are really different 816 self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno())) 817 # Make sure invalid values don't cause issues on win32 818 if sys.platform == "win32": 819 with self.assertRaises(OSError): 820 # Invalid file descriptors shouldn't display assert 821 # dialogs (#4804) 822 ntpath.sameopenfile(-1, -1) 823 824 def test_ismount(self): 825 self.assertTrue(ntpath.ismount("c:\\")) 826 self.assertTrue(ntpath.ismount("C:\\")) 827 self.assertTrue(ntpath.ismount("c:/")) 828 self.assertTrue(ntpath.ismount("C:/")) 829 self.assertTrue(ntpath.ismount("\\\\.\\c:\\")) 830 self.assertTrue(ntpath.ismount("\\\\.\\C:\\")) 831 832 self.assertTrue(ntpath.ismount(b"c:\\")) 833 self.assertTrue(ntpath.ismount(b"C:\\")) 834 self.assertTrue(ntpath.ismount(b"c:/")) 835 self.assertTrue(ntpath.ismount(b"C:/")) 836 self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\")) 837 self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\")) 838 839 with os_helper.temp_dir() as d: 840 self.assertFalse(ntpath.ismount(d)) 841 842 if sys.platform == "win32": 843 # 844 # Make sure the current folder isn't the root folder 845 # (or any other volume root). The drive-relative 846 # locations below cannot then refer to mount points 847 # 848 test_cwd = os.getenv("SystemRoot") 849 drive, path = ntpath.splitdrive(test_cwd) 850 with os_helper.change_cwd(test_cwd): 851 self.assertFalse(ntpath.ismount(drive.lower())) 852 self.assertFalse(ntpath.ismount(drive.upper())) 853 854 self.assertTrue(ntpath.ismount("\\\\localhost\\c$")) 855 self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\")) 856 857 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$")) 858 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\")) 859 860 def assertEqualCI(self, s1, s2): 861 """Assert that two strings are equal ignoring case differences.""" 862 self.assertEqual(s1.lower(), s2.lower()) 863 864 @unittest.skipUnless(nt, "OS helpers require 'nt' module") 865 def test_nt_helpers(self): 866 # Trivial validation that the helpers do not break, and support both 867 # unicode and bytes (UTF-8) paths 868 869 executable = nt._getfinalpathname(sys.executable) 870 871 for path in executable, os.fsencode(executable): 872 volume_path = nt._getvolumepathname(path) 873 path_drive = ntpath.splitdrive(path)[0] 874 volume_path_drive = ntpath.splitdrive(volume_path)[0] 875 self.assertEqualCI(path_drive, volume_path_drive) 876 877 cap, free = nt._getdiskusage(sys.exec_prefix) 878 self.assertGreater(cap, 0) 879 self.assertGreater(free, 0) 880 b_cap, b_free = nt._getdiskusage(sys.exec_prefix.encode()) 881 # Free space may change, so only test the capacity is equal 882 self.assertEqual(b_cap, cap) 883 self.assertGreater(b_free, 0) 884 885 for path in [sys.prefix, sys.executable]: 886 final_path = nt._getfinalpathname(path) 887 self.assertIsInstance(final_path, str) 888 self.assertGreater(len(final_path), 0) 889 890 b_final_path = nt._getfinalpathname(path.encode()) 891 self.assertIsInstance(b_final_path, bytes) 892 self.assertGreater(len(b_final_path), 0) 893 894class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase): 895 pathmodule = ntpath 896 attributes = ['relpath'] 897 898 899class PathLikeTests(NtpathTestCase): 900 901 path = ntpath 902 903 def setUp(self): 904 self.file_name = os_helper.TESTFN 905 self.file_path = FakePath(os_helper.TESTFN) 906 self.addCleanup(os_helper.unlink, self.file_name) 907 with open(self.file_name, 'xb', 0) as file: 908 file.write(b"test_ntpath.PathLikeTests") 909 910 def _check_function(self, func): 911 self.assertPathEqual(func(self.file_path), func(self.file_name)) 912 913 def test_path_normcase(self): 914 self._check_function(self.path.normcase) 915 if sys.platform == 'win32': 916 self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ') 917 918 def test_path_isabs(self): 919 self._check_function(self.path.isabs) 920 921 def test_path_join(self): 922 self.assertEqual(self.path.join('a', FakePath('b'), 'c'), 923 self.path.join('a', 'b', 'c')) 924 925 def test_path_split(self): 926 self._check_function(self.path.split) 927 928 def test_path_splitext(self): 929 self._check_function(self.path.splitext) 930 931 def test_path_splitdrive(self): 932 self._check_function(self.path.splitdrive) 933 934 def test_path_basename(self): 935 self._check_function(self.path.basename) 936 937 def test_path_dirname(self): 938 self._check_function(self.path.dirname) 939 940 def test_path_islink(self): 941 self._check_function(self.path.islink) 942 943 def test_path_lexists(self): 944 self._check_function(self.path.lexists) 945 946 def test_path_ismount(self): 947 self._check_function(self.path.ismount) 948 949 def test_path_expanduser(self): 950 self._check_function(self.path.expanduser) 951 952 def test_path_expandvars(self): 953 self._check_function(self.path.expandvars) 954 955 def test_path_normpath(self): 956 self._check_function(self.path.normpath) 957 958 def test_path_abspath(self): 959 self._check_function(self.path.abspath) 960 961 def test_path_realpath(self): 962 self._check_function(self.path.realpath) 963 964 def test_path_relpath(self): 965 self._check_function(self.path.relpath) 966 967 def test_path_commonpath(self): 968 common_path = self.path.commonpath([self.file_path, self.file_name]) 969 self.assertPathEqual(common_path, self.file_name) 970 971 def test_path_isdir(self): 972 self._check_function(self.path.isdir) 973 974 975if __name__ == "__main__": 976 unittest.main() 977