blob: a8f764f48ca00f51d2799bd45b19d7560a4bea5d [file] [log] [blame]
Guido van Rossumead9d8d1999-02-03 17:21:21 +00001import ntpath
Mark Hammond673c6cf2000-08-14 06:21:26 +00002import os
Brian Curtin13a0db52010-09-06 19:46:17 +00003import sys
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004import unittest
5import warnings
Hai Shi46605972020-08-04 00:49:18 +08006from test.support import os_helper
7from test.support import TestFailed
8from test.support.os_helper import FakePath
Hai Shi598a9512020-08-07 23:18:38 +08009from test import test_genericpath
Brian Curtin62857742010-09-06 17:07:27 +000010from tempfile import TemporaryFile
Guido van Rossumead9d8d1999-02-03 17:21:21 +000011
Steve Dower75e06492019-08-21 13:43:06 -070012
Steve Dower23ad6d02018-02-22 10:39:10 -080013try:
14 import nt
15except ImportError:
16 # Most tests can complete without the nt module,
17 # but for those that require it we import here.
18 nt = None
Guido van Rossumead9d8d1999-02-03 17:21:21 +000019
Steve Dower75e06492019-08-21 13:43:06 -070020try:
21 ntpath._getfinalpathname
22except AttributeError:
23 HAVE_GETFINALPATHNAME = False
24else:
25 HAVE_GETFINALPATHNAME = True
26
Steve Dower7c6130c2019-11-15 16:04:00 -080027try:
28 import ctypes
29except ImportError:
30 HAVE_GETSHORTPATHNAME = False
31else:
32 HAVE_GETSHORTPATHNAME = True
33 def _getshortpathname(path):
34 GSPN = ctypes.WinDLL("kernel32", use_last_error=True).GetShortPathNameW
35 GSPN.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32]
36 GSPN.restype = ctypes.c_uint32
37 result_len = GSPN(path, None, 0)
38 if not result_len:
39 raise OSError("failed to get short path name 0x{:08X}"
40 .format(ctypes.get_last_error()))
41 result = ctypes.create_unicode_buffer(result_len)
42 result_len = GSPN(path, result, result_len)
43 return result[:result_len]
Steve Dower75e06492019-08-21 13:43:06 -070044
Steve Dower97d79062019-09-10 14:52:48 +010045def _norm(path):
46 if isinstance(path, (bytes, str, os.PathLike)):
47 return ntpath.normcase(os.fsdecode(path))
48 elif hasattr(path, "__iter__"):
49 return tuple(ntpath.normcase(os.fsdecode(p)) for p in path)
50 return path
51
52
Guido van Rossumead9d8d1999-02-03 17:21:21 +000053def tester(fn, wantResult):
Eric S. Raymondfc170b12001-02-09 11:51:27 +000054 fn = fn.replace("\\", "\\\\")
Fred Drake004d5e62000-10-23 17:22:08 +000055 gotResult = eval(fn)
Steve Dower97d79062019-09-10 14:52:48 +010056 if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
Christian Heimesf6cd9672008-03-26 13:45:42 +000057 raise TestFailed("%s should return: %s but returned: %s" \
58 %(str(fn), str(wantResult), str(gotResult)))
Tim Peters6578dc92002-12-24 18:31:27 +000059
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +000060 # then with bytes
61 fn = fn.replace("('", "(b'")
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"')
Serhiy Storchakadbb10192014-02-13 10:13:53 +020067 fn = os.fsencode(fn).decode('latin1')
68 fn = fn.encode('ascii', 'backslashreplace').decode('ascii')
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010069 with warnings.catch_warnings():
70 warnings.simplefilter("ignore", DeprecationWarning)
71 gotResult = eval(fn)
Steve Dower97d79062019-09-10 14:52:48 +010072 if _norm(wantResult) != _norm(gotResult):
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +000073 raise TestFailed("%s should return: %s but returned: %s" \
74 %(str(fn), str(wantResult), repr(gotResult)))
Guido van Rossumead9d8d1999-02-03 17:21:21 +000075
Mark Hammond5a607a32009-05-06 08:04:54 +000076
Steve Dower97d79062019-09-10 14:52:48 +010077class NtpathTestCase(unittest.TestCase):
78 def assertPathEqual(self, path1, path2):
79 if path1 == path2 or _norm(path1) == _norm(path2):
80 return
81 self.assertEqual(path1, path2)
82
83 def assertPathIn(self, path, pathset):
84 self.assertIn(_norm(path), _norm(pathset))
85
86
87class TestNtpath(NtpathTestCase):
Christian Heimesf6cd9672008-03-26 13:45:42 +000088 def test_splitext(self):
89 tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
90 tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
91 tester('ntpath.splitext(".ext")', ('.ext', ''))
92 tester('ntpath.splitext("\\foo.ext\\foo")', ('\\foo.ext\\foo', ''))
93 tester('ntpath.splitext("foo.ext\\")', ('foo.ext\\', ''))
94 tester('ntpath.splitext("")', ('', ''))
95 tester('ntpath.splitext("foo.bar.ext")', ('foo.bar', '.ext'))
96 tester('ntpath.splitext("xx/foo.bar.ext")', ('xx/foo.bar', '.ext'))
97 tester('ntpath.splitext("xx\\foo.bar.ext")', ('xx\\foo.bar', '.ext'))
98 tester('ntpath.splitext("c:a/b\\c.d")', ('c:a/b\\c', '.d'))
Guido van Rossumead9d8d1999-02-03 17:21:21 +000099
Christian Heimesf6cd9672008-03-26 13:45:42 +0000100 def test_splitdrive(self):
101 tester('ntpath.splitdrive("c:\\foo\\bar")',
102 ('c:', '\\foo\\bar'))
103 tester('ntpath.splitdrive("c:/foo/bar")',
104 ('c:', '/foo/bar'))
Mark Hammond5a607a32009-05-06 08:04:54 +0000105 tester('ntpath.splitdrive("\\\\conky\\mountpoint\\foo\\bar")',
Christian Heimesf6cd9672008-03-26 13:45:42 +0000106 ('\\\\conky\\mountpoint', '\\foo\\bar'))
Mark Hammond5a607a32009-05-06 08:04:54 +0000107 tester('ntpath.splitdrive("//conky/mountpoint/foo/bar")',
Christian Heimesf6cd9672008-03-26 13:45:42 +0000108 ('//conky/mountpoint', '/foo/bar'))
Mark Hammond5a607a32009-05-06 08:04:54 +0000109 tester('ntpath.splitdrive("\\\\\\conky\\mountpoint\\foo\\bar")',
110 ('', '\\\\\\conky\\mountpoint\\foo\\bar'))
111 tester('ntpath.splitdrive("///conky/mountpoint/foo/bar")',
112 ('', '///conky/mountpoint/foo/bar'))
113 tester('ntpath.splitdrive("\\\\conky\\\\mountpoint\\foo\\bar")',
114 ('', '\\\\conky\\\\mountpoint\\foo\\bar'))
115 tester('ntpath.splitdrive("//conky//mountpoint/foo/bar")',
116 ('', '//conky//mountpoint/foo/bar'))
Serhiy Storchaka3d7e1152013-12-16 14:34:55 +0200117 # Issue #19911: UNC part containing U+0130
118 self.assertEqual(ntpath.splitdrive('//conky/MOUNTPOİNT/foo/bar'),
119 ('//conky/MOUNTPOİNT', '/foo/bar'))
Guido van Rossumead9d8d1999-02-03 17:21:21 +0000120
Christian Heimesf6cd9672008-03-26 13:45:42 +0000121 def test_split(self):
122 tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
123 tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")',
124 ('\\\\conky\\mountpoint\\foo', 'bar'))
Guido van Rossumead9d8d1999-02-03 17:21:21 +0000125
Christian Heimesf6cd9672008-03-26 13:45:42 +0000126 tester('ntpath.split("c:\\")', ('c:\\', ''))
127 tester('ntpath.split("\\\\conky\\mountpoint\\")',
Mark Hammond5a607a32009-05-06 08:04:54 +0000128 ('\\\\conky\\mountpoint\\', ''))
Guido van Rossumead9d8d1999-02-03 17:21:21 +0000129
Christian Heimesf6cd9672008-03-26 13:45:42 +0000130 tester('ntpath.split("c:/")', ('c:/', ''))
Mark Hammond5a607a32009-05-06 08:04:54 +0000131 tester('ntpath.split("//conky/mountpoint/")', ('//conky/mountpoint/', ''))
Mark Hammond673c6cf2000-08-14 06:21:26 +0000132
Christian Heimesf6cd9672008-03-26 13:45:42 +0000133 def test_isabs(self):
134 tester('ntpath.isabs("c:\\")', 1)
135 tester('ntpath.isabs("\\\\conky\\mountpoint\\")', 1)
136 tester('ntpath.isabs("\\foo")', 1)
137 tester('ntpath.isabs("\\foo\\bar")', 1)
Tim Petersd4f7f602001-07-19 19:11:41 +0000138
Christian Heimesf6cd9672008-03-26 13:45:42 +0000139 def test_commonprefix(self):
140 tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
141 "/home/swen")
142 tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
143 "\\home\\swen\\")
144 tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
145 "/home/swen/spam")
Tim Peters6a3e5f12001-11-05 21:25:02 +0000146
Christian Heimesf6cd9672008-03-26 13:45:42 +0000147 def test_join(self):
148 tester('ntpath.join("")', '')
149 tester('ntpath.join("", "", "")', '')
150 tester('ntpath.join("a")', 'a')
151 tester('ntpath.join("/a")', '/a')
152 tester('ntpath.join("\\a")', '\\a')
153 tester('ntpath.join("a:")', 'a:')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000154 tester('ntpath.join("a:", "\\b")', 'a:\\b')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000155 tester('ntpath.join("a", "\\b")', '\\b')
156 tester('ntpath.join("a", "b", "c")', 'a\\b\\c')
157 tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c')
158 tester('ntpath.join("a", "b\\", "c")', 'a\\b\\c')
159 tester('ntpath.join("a", "b", "\\c")', '\\c')
160 tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep')
161 tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b')
Tim Peters54a14a32001-08-30 22:05:26 +0000162
Christian Heimesf6cd9672008-03-26 13:45:42 +0000163 tester("ntpath.join('', 'a')", 'a')
164 tester("ntpath.join('', '', '', '', 'a')", 'a')
165 tester("ntpath.join('a', '')", 'a\\')
166 tester("ntpath.join('a', '', '', '', '')", 'a\\')
167 tester("ntpath.join('a\\', '')", 'a\\')
168 tester("ntpath.join('a\\', '', '', '', '')", 'a\\')
Serhiy Storchakac369c2c2014-01-27 23:15:14 +0200169 tester("ntpath.join('a/', '')", 'a/')
Tim Peters54a14a32001-08-30 22:05:26 +0000170
Serhiy Storchakac369c2c2014-01-27 23:15:14 +0200171 tester("ntpath.join('a/b', 'x/y')", 'a/b\\x/y')
172 tester("ntpath.join('/a/b', 'x/y')", '/a/b\\x/y')
173 tester("ntpath.join('/a/b/', 'x/y')", '/a/b/x/y')
174 tester("ntpath.join('c:', 'x/y')", 'c:x/y')
175 tester("ntpath.join('c:a/b', 'x/y')", 'c:a/b\\x/y')
176 tester("ntpath.join('c:a/b/', 'x/y')", 'c:a/b/x/y')
177 tester("ntpath.join('c:/', 'x/y')", 'c:/x/y')
178 tester("ntpath.join('c:/a/b', 'x/y')", 'c:/a/b\\x/y')
179 tester("ntpath.join('c:/a/b/', 'x/y')", 'c:/a/b/x/y')
180 tester("ntpath.join('//computer/share', 'x/y')", '//computer/share\\x/y')
181 tester("ntpath.join('//computer/share/', 'x/y')", '//computer/share/x/y')
182 tester("ntpath.join('//computer/share/a/b', 'x/y')", '//computer/share/a/b\\x/y')
Mark Hammond5a607a32009-05-06 08:04:54 +0000183
Serhiy Storchakac369c2c2014-01-27 23:15:14 +0200184 tester("ntpath.join('a/b', '/x/y')", '/x/y')
185 tester("ntpath.join('/a/b', '/x/y')", '/x/y')
186 tester("ntpath.join('c:', '/x/y')", 'c:/x/y')
187 tester("ntpath.join('c:a/b', '/x/y')", 'c:/x/y')
188 tester("ntpath.join('c:/', '/x/y')", 'c:/x/y')
189 tester("ntpath.join('c:/a/b', '/x/y')", 'c:/x/y')
190 tester("ntpath.join('//computer/share', '/x/y')", '//computer/share/x/y')
191 tester("ntpath.join('//computer/share/', '/x/y')", '//computer/share/x/y')
192 tester("ntpath.join('//computer/share/a', '/x/y')", '//computer/share/x/y')
193
194 tester("ntpath.join('c:', 'C:x/y')", 'C:x/y')
195 tester("ntpath.join('c:a/b', 'C:x/y')", 'C:a/b\\x/y')
196 tester("ntpath.join('c:/', 'C:x/y')", 'C:/x/y')
197 tester("ntpath.join('c:/a/b', 'C:x/y')", 'C:/a/b\\x/y')
198
199 for x in ('', 'a/b', '/a/b', 'c:', 'c:a/b', 'c:/', 'c:/a/b',
200 '//computer/share', '//computer/share/', '//computer/share/a/b'):
201 for y in ('d:', 'd:x/y', 'd:/', 'd:/x/y',
202 '//machine/common', '//machine/common/', '//machine/common/x/y'):
203 tester("ntpath.join(%r, %r)" % (x, y), y)
Mark Hammond5a607a32009-05-06 08:04:54 +0000204
205 tester("ntpath.join('\\\\computer\\share\\', 'a', 'b')", '\\\\computer\\share\\a\\b')
206 tester("ntpath.join('\\\\computer\\share', 'a', 'b')", '\\\\computer\\share\\a\\b')
207 tester("ntpath.join('\\\\computer\\share', 'a\\b')", '\\\\computer\\share\\a\\b')
208 tester("ntpath.join('//computer/share/', 'a', 'b')", '//computer/share/a\\b')
209 tester("ntpath.join('//computer/share', 'a', 'b')", '//computer/share\\a\\b')
210 tester("ntpath.join('//computer/share', 'a/b')", '//computer/share\\a/b')
211
Christian Heimesf6cd9672008-03-26 13:45:42 +0000212 def test_normpath(self):
213 tester("ntpath.normpath('A//////././//.//B')", r'A\B')
214 tester("ntpath.normpath('A/./B')", r'A\B')
215 tester("ntpath.normpath('A/foo/../B')", r'A\B')
216 tester("ntpath.normpath('C:A//B')", r'C:A\B')
217 tester("ntpath.normpath('D:A/./B')", r'D:A\B')
218 tester("ntpath.normpath('e:A/foo/../B')", r'e:A\B')
Tim Peters54a14a32001-08-30 22:05:26 +0000219
Christian Heimesf6cd9672008-03-26 13:45:42 +0000220 tester("ntpath.normpath('C:///A//B')", r'C:\A\B')
221 tester("ntpath.normpath('D:///A/./B')", r'D:\A\B')
222 tester("ntpath.normpath('e:///A/foo/../B')", r'e:\A\B')
Thomas Woutersb2137042007-02-01 18:02:27 +0000223
Christian Heimesf6cd9672008-03-26 13:45:42 +0000224 tester("ntpath.normpath('..')", r'..')
225 tester("ntpath.normpath('.')", r'.')
226 tester("ntpath.normpath('')", r'.')
227 tester("ntpath.normpath('/')", '\\')
228 tester("ntpath.normpath('c:/')", 'c:\\')
229 tester("ntpath.normpath('/../.././..')", '\\')
230 tester("ntpath.normpath('c:/../../..')", 'c:\\')
231 tester("ntpath.normpath('../.././..')", r'..\..\..')
232 tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
233 tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
234 tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
Fred Drake5e997312002-01-15 03:46:43 +0000235
Georg Brandlcfb68212010-07-31 21:40:15 +0000236 tester("ntpath.normpath('\\\\.\\NUL')", r'\\.\NUL')
237 tester("ntpath.normpath('\\\\?\\D:/XY\\Z')", r'\\?\D:/XY\Z')
238
Steve Dower75e06492019-08-21 13:43:06 -0700239 def test_realpath_curdir(self):
240 expected = ntpath.normpath(os.getcwd())
241 tester("ntpath.realpath('.')", expected)
242 tester("ntpath.realpath('./.')", expected)
243 tester("ntpath.realpath('/'.join(['.'] * 100))", expected)
244 tester("ntpath.realpath('.\\.')", expected)
245 tester("ntpath.realpath('\\'.join(['.'] * 100))", expected)
246
247 def test_realpath_pardir(self):
248 expected = ntpath.normpath(os.getcwd())
249 tester("ntpath.realpath('..')", ntpath.dirname(expected))
250 tester("ntpath.realpath('../..')",
251 ntpath.dirname(ntpath.dirname(expected)))
252 tester("ntpath.realpath('/'.join(['..'] * 50))",
253 ntpath.splitdrive(expected)[0] + '\\')
254 tester("ntpath.realpath('..\\..')",
255 ntpath.dirname(ntpath.dirname(expected)))
256 tester("ntpath.realpath('\\'.join(['..'] * 50))",
257 ntpath.splitdrive(expected)[0] + '\\')
258
Hai Shi46605972020-08-04 00:49:18 +0800259 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700260 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
261 def test_realpath_basic(self):
Hai Shi46605972020-08-04 00:49:18 +0800262 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700263 open(ABSTFN, "wb").close()
Hai Shi46605972020-08-04 00:49:18 +0800264 self.addCleanup(os_helper.unlink, ABSTFN)
265 self.addCleanup(os_helper.unlink, ABSTFN + "1")
Steve Dower75e06492019-08-21 13:43:06 -0700266
267 os.symlink(ABSTFN, ABSTFN + "1")
Steve Dower97d79062019-09-10 14:52:48 +0100268 self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
269 self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")),
Steve Dower75e06492019-08-21 13:43:06 -0700270 os.fsencode(ABSTFN))
271
Hai Shi46605972020-08-04 00:49:18 +0800272 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700273 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
274 def test_realpath_relative(self):
Hai Shi46605972020-08-04 00:49:18 +0800275 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700276 open(ABSTFN, "wb").close()
Hai Shi46605972020-08-04 00:49:18 +0800277 self.addCleanup(os_helper.unlink, ABSTFN)
278 self.addCleanup(os_helper.unlink, ABSTFN + "1")
Steve Dower75e06492019-08-21 13:43:06 -0700279
280 os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1"))
Steve Dower97d79062019-09-10 14:52:48 +0100281 self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700282
Hai Shi46605972020-08-04 00:49:18 +0800283 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700284 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
285 def test_realpath_broken_symlinks(self):
Hai Shi46605972020-08-04 00:49:18 +0800286 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700287 os.mkdir(ABSTFN)
Hai Shi79bb2c92020-08-06 19:51:29 +0800288 self.addCleanup(os_helper.rmtree, ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700289
Hai Shi598a9512020-08-07 23:18:38 +0800290 with os_helper.change_cwd(ABSTFN):
Steve Dower75e06492019-08-21 13:43:06 -0700291 os.mkdir("subdir")
292 os.chdir("subdir")
293 os.symlink(".", "recursive")
294 os.symlink("..", "parent")
295 os.chdir("..")
296 os.symlink(".", "self")
297 os.symlink("missing", "broken")
298 os.symlink(r"broken\bar", "broken1")
299 os.symlink(r"self\self\broken", "broken2")
300 os.symlink(r"subdir\parent\subdir\parent\broken", "broken3")
301 os.symlink(ABSTFN + r"\broken", "broken4")
302 os.symlink(r"recursive\..\broken", "broken5")
303
Steve Dower97d79062019-09-10 14:52:48 +0100304 self.assertPathEqual(ntpath.realpath("broken"),
305 ABSTFN + r"\missing")
306 self.assertPathEqual(ntpath.realpath(r"broken\foo"),
307 ABSTFN + r"\missing\foo")
Steve Dowerabde52c2019-11-15 09:49:21 -0800308 # bpo-38453: We no longer recursively resolve segments of relative
309 # symlinks that the OS cannot resolve.
Steve Dower97d79062019-09-10 14:52:48 +0100310 self.assertPathEqual(ntpath.realpath(r"broken1"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800311 ABSTFN + r"\broken\bar")
Steve Dower97d79062019-09-10 14:52:48 +0100312 self.assertPathEqual(ntpath.realpath(r"broken1\baz"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800313 ABSTFN + r"\broken\bar\baz")
Steve Dower97d79062019-09-10 14:52:48 +0100314 self.assertPathEqual(ntpath.realpath("broken2"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800315 ABSTFN + r"\self\self\missing")
Steve Dower97d79062019-09-10 14:52:48 +0100316 self.assertPathEqual(ntpath.realpath("broken3"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800317 ABSTFN + r"\subdir\parent\subdir\parent\missing")
Steve Dower97d79062019-09-10 14:52:48 +0100318 self.assertPathEqual(ntpath.realpath("broken4"),
319 ABSTFN + r"\missing")
320 self.assertPathEqual(ntpath.realpath("broken5"),
321 ABSTFN + r"\missing")
Steve Dower75e06492019-08-21 13:43:06 -0700322
Steve Dower97d79062019-09-10 14:52:48 +0100323 self.assertPathEqual(ntpath.realpath(b"broken"),
324 os.fsencode(ABSTFN + r"\missing"))
325 self.assertPathEqual(ntpath.realpath(rb"broken\foo"),
326 os.fsencode(ABSTFN + r"\missing\foo"))
327 self.assertPathEqual(ntpath.realpath(rb"broken1"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800328 os.fsencode(ABSTFN + r"\broken\bar"))
Steve Dower97d79062019-09-10 14:52:48 +0100329 self.assertPathEqual(ntpath.realpath(rb"broken1\baz"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800330 os.fsencode(ABSTFN + r"\broken\bar\baz"))
Steve Dower97d79062019-09-10 14:52:48 +0100331 self.assertPathEqual(ntpath.realpath(b"broken2"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800332 os.fsencode(ABSTFN + r"\self\self\missing"))
Steve Dower97d79062019-09-10 14:52:48 +0100333 self.assertPathEqual(ntpath.realpath(rb"broken3"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800334 os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing"))
Steve Dower97d79062019-09-10 14:52:48 +0100335 self.assertPathEqual(ntpath.realpath(b"broken4"),
336 os.fsencode(ABSTFN + r"\missing"))
337 self.assertPathEqual(ntpath.realpath(b"broken5"),
338 os.fsencode(ABSTFN + r"\missing"))
Steve Dower75e06492019-08-21 13:43:06 -0700339
Hai Shi46605972020-08-04 00:49:18 +0800340 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700341 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
342 def test_realpath_symlink_loops(self):
Steve Dowerabde52c2019-11-15 09:49:21 -0800343 # Symlink loops are non-deterministic as to which path is returned, but
344 # it will always be the fully resolved path of one member of the cycle
Hai Shi46605972020-08-04 00:49:18 +0800345 ABSTFN = ntpath.abspath(os_helper.TESTFN)
346 self.addCleanup(os_helper.unlink, ABSTFN)
347 self.addCleanup(os_helper.unlink, ABSTFN + "1")
348 self.addCleanup(os_helper.unlink, ABSTFN + "2")
349 self.addCleanup(os_helper.unlink, ABSTFN + "y")
350 self.addCleanup(os_helper.unlink, ABSTFN + "c")
351 self.addCleanup(os_helper.unlink, ABSTFN + "a")
Steve Dower75e06492019-08-21 13:43:06 -0700352
Steve Dower75e06492019-08-21 13:43:06 -0700353 os.symlink(ABSTFN, ABSTFN)
Steve Dowera0e3d272019-10-03 08:31:03 -0700354 self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700355
Steve Dower75e06492019-08-21 13:43:06 -0700356 os.symlink(ABSTFN + "1", ABSTFN + "2")
357 os.symlink(ABSTFN + "2", ABSTFN + "1")
Steve Dowera0e3d272019-10-03 08:31:03 -0700358 expected = (ABSTFN + "1", ABSTFN + "2")
Steve Dower97d79062019-09-10 14:52:48 +0100359 self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected)
360 self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected)
Steve Dower75e06492019-08-21 13:43:06 -0700361
Steve Dower97d79062019-09-10 14:52:48 +0100362 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\x"),
363 (ntpath.join(r, "x") for r in expected))
364 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."),
365 ntpath.dirname(ABSTFN))
366 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
367 ntpath.dirname(ABSTFN) + "\\x")
Steve Dower75e06492019-08-21 13:43:06 -0700368 os.symlink(ABSTFN + "x", ABSTFN + "y")
Steve Dower97d79062019-09-10 14:52:48 +0100369 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\"
370 + ntpath.basename(ABSTFN) + "y"),
371 ABSTFN + "x")
372 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\..\\"
373 + ntpath.basename(ABSTFN) + "1"),
374 expected)
Steve Dower75e06492019-08-21 13:43:06 -0700375
376 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
Steve Dowera0e3d272019-10-03 08:31:03 -0700377 self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), ABSTFN + "a")
Steve Dower75e06492019-08-21 13:43:06 -0700378
379 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
380 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
Steve Dowera0e3d272019-10-03 08:31:03 -0700381 self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), ABSTFN + "c")
Steve Dower75e06492019-08-21 13:43:06 -0700382
383 # Test using relative path as well.
Steve Dowera0e3d272019-10-03 08:31:03 -0700384 self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700385
Hai Shi46605972020-08-04 00:49:18 +0800386 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700387 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
388 def test_realpath_symlink_prefix(self):
Hai Shi46605972020-08-04 00:49:18 +0800389 ABSTFN = ntpath.abspath(os_helper.TESTFN)
390 self.addCleanup(os_helper.unlink, ABSTFN + "3")
391 self.addCleanup(os_helper.unlink, "\\\\?\\" + ABSTFN + "3.")
392 self.addCleanup(os_helper.unlink, ABSTFN + "3link")
393 self.addCleanup(os_helper.unlink, ABSTFN + "3.link")
Steve Dower75e06492019-08-21 13:43:06 -0700394
395 with open(ABSTFN + "3", "wb") as f:
396 f.write(b'0')
397 os.symlink(ABSTFN + "3", ABSTFN + "3link")
398
399 with open("\\\\?\\" + ABSTFN + "3.", "wb") as f:
400 f.write(b'1')
401 os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link")
402
Steve Dower97d79062019-09-10 14:52:48 +0100403 self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"),
404 ABSTFN + "3")
405 self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"),
406 "\\\\?\\" + ABSTFN + "3.")
Steve Dower75e06492019-08-21 13:43:06 -0700407
408 # Resolved paths should be usable to open target files
409 with open(ntpath.realpath(ABSTFN + "3link"), "rb") as f:
410 self.assertEqual(f.read(), b'0')
411 with open(ntpath.realpath(ABSTFN + "3.link"), "rb") as f:
412 self.assertEqual(f.read(), b'1')
413
414 # When the prefix is included, it is not stripped
Steve Dower97d79062019-09-10 14:52:48 +0100415 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"),
416 "\\\\?\\" + ABSTFN + "3")
417 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"),
418 "\\\\?\\" + ABSTFN + "3.")
Steve Dower75e06492019-08-21 13:43:06 -0700419
Steve Dower92521fe2019-09-11 10:48:36 +0100420 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
421 def test_realpath_nul(self):
422 tester("ntpath.realpath('NUL')", r'\\.\NUL')
423
Steve Dowerabde52c2019-11-15 09:49:21 -0800424 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
Steve Dower7c6130c2019-11-15 16:04:00 -0800425 @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname')
Steve Dowerabde52c2019-11-15 09:49:21 -0800426 def test_realpath_cwd(self):
Hai Shi46605972020-08-04 00:49:18 +0800427 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dowerabde52c2019-11-15 09:49:21 -0800428
Hai Shi46605972020-08-04 00:49:18 +0800429 os_helper.unlink(ABSTFN)
Hai Shi79bb2c92020-08-06 19:51:29 +0800430 os_helper.rmtree(ABSTFN)
Steve Dowerabde52c2019-11-15 09:49:21 -0800431 os.mkdir(ABSTFN)
Hai Shi79bb2c92020-08-06 19:51:29 +0800432 self.addCleanup(os_helper.rmtree, ABSTFN)
Steve Dowerabde52c2019-11-15 09:49:21 -0800433
434 test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName")
Steve Dower7c6130c2019-11-15 16:04:00 -0800435 os.mkdir(test_dir_long)
436
437 test_dir_short = _getshortpathname(test_dir_long)
Steve Dowerabde52c2019-11-15 09:49:21 -0800438 test_file_long = ntpath.join(test_dir_long, "file.txt")
439 test_file_short = ntpath.join(test_dir_short, "file.txt")
440
Steve Dowerabde52c2019-11-15 09:49:21 -0800441 with open(test_file_long, "wb") as f:
442 f.write(b"content")
443
444 self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short))
445
Hai Shi598a9512020-08-07 23:18:38 +0800446 with os_helper.change_cwd(test_dir_long):
Steve Dowerabde52c2019-11-15 09:49:21 -0800447 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
Hai Shi598a9512020-08-07 23:18:38 +0800448 with os_helper.change_cwd(test_dir_long.lower()):
Steve Dowerabde52c2019-11-15 09:49:21 -0800449 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
Hai Shi598a9512020-08-07 23:18:38 +0800450 with os_helper.change_cwd(test_dir_short):
Steve Dowerabde52c2019-11-15 09:49:21 -0800451 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
452
Christian Heimesf6cd9672008-03-26 13:45:42 +0000453 def test_expandvars(self):
Hai Shi46605972020-08-04 00:49:18 +0800454 with os_helper.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000455 env.clear()
456 env["foo"] = "bar"
457 env["{foo"] = "baz1"
458 env["{foo}"] = "baz2"
Christian Heimesf6cd9672008-03-26 13:45:42 +0000459 tester('ntpath.expandvars("foo")', "foo")
460 tester('ntpath.expandvars("$foo bar")', "bar bar")
461 tester('ntpath.expandvars("${foo}bar")', "barbar")
462 tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar")
463 tester('ntpath.expandvars("$bar bar")', "$bar bar")
464 tester('ntpath.expandvars("$?bar")', "$?bar")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000465 tester('ntpath.expandvars("$foo}bar")', "bar}bar")
466 tester('ntpath.expandvars("${foo")', "${foo")
467 tester('ntpath.expandvars("${{foo}}")', "baz1}")
468 tester('ntpath.expandvars("$foo$foo")', "barbar")
469 tester('ntpath.expandvars("$bar$bar")', "$bar$bar")
470 tester('ntpath.expandvars("%foo% bar")', "bar bar")
471 tester('ntpath.expandvars("%foo%bar")', "barbar")
472 tester('ntpath.expandvars("%foo%%foo%")', "barbar")
473 tester('ntpath.expandvars("%%foo%%foo%foo%")', "%foo%foobar")
474 tester('ntpath.expandvars("%?bar%")', "%?bar%")
475 tester('ntpath.expandvars("%foo%%bar")', "bar%bar")
476 tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar")
Serhiy Storchaka1b87ae02015-03-25 16:40:15 +0200477 tester('ntpath.expandvars("bar\'%foo%")', "bar\'%foo%")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000478
Hai Shi46605972020-08-04 00:49:18 +0800479 @unittest.skipUnless(os_helper.FS_NONASCII, 'need os_helper.FS_NONASCII')
Serhiy Storchakadbb10192014-02-13 10:13:53 +0200480 def test_expandvars_nonascii(self):
481 def check(value, expected):
482 tester('ntpath.expandvars(%r)' % value, expected)
Hai Shi46605972020-08-04 00:49:18 +0800483 with os_helper.EnvironmentVarGuard() as env:
Serhiy Storchakadbb10192014-02-13 10:13:53 +0200484 env.clear()
Hai Shi46605972020-08-04 00:49:18 +0800485 nonascii = os_helper.FS_NONASCII
Serhiy Storchakadbb10192014-02-13 10:13:53 +0200486 env['spam'] = nonascii
487 env[nonascii] = 'ham' + nonascii
488 check('$spam bar', '%s bar' % nonascii)
489 check('$%s bar' % nonascii, '$%s bar' % nonascii)
490 check('${spam}bar', '%sbar' % nonascii)
491 check('${%s}bar' % nonascii, 'ham%sbar' % nonascii)
492 check('$spam}bar', '%s}bar' % nonascii)
493 check('$%s}bar' % nonascii, '$%s}bar' % nonascii)
494 check('%spam% bar', '%s bar' % nonascii)
495 check('%{}% bar'.format(nonascii), 'ham%s bar' % nonascii)
496 check('%spam%bar', '%sbar' % nonascii)
497 check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii)
498
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300499 def test_expanduser(self):
500 tester('ntpath.expanduser("test")', 'test')
501
Hai Shi46605972020-08-04 00:49:18 +0800502 with os_helper.EnvironmentVarGuard() as env:
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300503 env.clear()
504 tester('ntpath.expanduser("~test")', '~test')
505
506 env['HOMEPATH'] = 'eric\\idle'
507 env['HOMEDRIVE'] = 'C:\\'
508 tester('ntpath.expanduser("~test")', 'C:\\eric\\test')
509 tester('ntpath.expanduser("~")', 'C:\\eric\\idle')
510
511 del env['HOMEDRIVE']
512 tester('ntpath.expanduser("~test")', 'eric\\test')
513 tester('ntpath.expanduser("~")', 'eric\\idle')
514
515 env.clear()
516 env['USERPROFILE'] = 'C:\\eric\\idle'
517 tester('ntpath.expanduser("~test")', 'C:\\eric\\test')
518 tester('ntpath.expanduser("~")', 'C:\\eric\\idle')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300519 tester('ntpath.expanduser("~test\\foo\\bar")',
Anthony Sottile25ec4a42019-03-12 08:39:57 -0700520 'C:\\eric\\test\\foo\\bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300521 tester('ntpath.expanduser("~test/foo/bar")',
Anthony Sottile25ec4a42019-03-12 08:39:57 -0700522 'C:\\eric\\test/foo/bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300523 tester('ntpath.expanduser("~\\foo\\bar")',
Anthony Sottile25ec4a42019-03-12 08:39:57 -0700524 'C:\\eric\\idle\\foo\\bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300525 tester('ntpath.expanduser("~/foo/bar")',
Anthony Sottile25ec4a42019-03-12 08:39:57 -0700526 'C:\\eric\\idle/foo/bar')
527
528 # bpo-36264: ignore `HOME` when set on windows
529 env.clear()
530 env['HOME'] = 'F:\\'
531 env['USERPROFILE'] = 'C:\\eric\\idle'
532 tester('ntpath.expanduser("~test")', 'C:\\eric\\test')
533 tester('ntpath.expanduser("~")', 'C:\\eric\\idle')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300534
Steve Dower23ad6d02018-02-22 10:39:10 -0800535 @unittest.skipUnless(nt, "abspath requires 'nt' module")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000536 def test_abspath(self):
Steve Dower23ad6d02018-02-22 10:39:10 -0800537 tester('ntpath.abspath("C:\\")', "C:\\")
Hai Shi46605972020-08-04 00:49:18 +0800538 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047
Franz Wöllertd2e902e2018-07-29 14:47:09 +0200539 tester('ntpath.abspath("")', cwd_dir)
540 tester('ntpath.abspath(" ")', cwd_dir + "\\ ")
541 tester('ntpath.abspath("?")', cwd_dir + "\\?")
Tim Grahamd03b7752018-10-25 11:26:38 -0400542 drive, _ = ntpath.splitdrive(cwd_dir)
543 tester('ntpath.abspath("/abc/")', drive + "\\abc")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000544
545 def test_relpath(self):
Christian Heimesf6cd9672008-03-26 13:45:42 +0000546 tester('ntpath.relpath("a")', 'a')
Steve Dower75e06492019-08-21 13:43:06 -0700547 tester('ntpath.relpath(ntpath.abspath("a"))', 'a')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000548 tester('ntpath.relpath("a/b")', 'a\\b')
549 tester('ntpath.relpath("../a/b")', '..\\a\\b')
Hai Shi46605972020-08-04 00:49:18 +0800550 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir:
Steve Dower75e06492019-08-21 13:43:06 -0700551 currentdir = ntpath.basename(cwd_dir)
Serhiy Storchaka5106d042015-01-26 10:26:14 +0200552 tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a')
553 tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000554 tester('ntpath.relpath("a", "b/c")', '..\\..\\a')
Mark Hammond5a607a32009-05-06 08:04:54 +0000555 tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000556 tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a')
557 tester('ntpath.relpath("a", "a")', '.')
Mark Hammond5a607a32009-05-06 08:04:54 +0000558 tester('ntpath.relpath("/foo/bar/bat", "/x/y/z")', '..\\..\\..\\foo\\bar\\bat')
559 tester('ntpath.relpath("/foo/bar/bat", "/foo/bar")', 'bat')
560 tester('ntpath.relpath("/foo/bar/bat", "/")', 'foo\\bar\\bat')
561 tester('ntpath.relpath("/", "/foo/bar/bat")', '..\\..\\..')
562 tester('ntpath.relpath("/foo/bar/bat", "/x")', '..\\foo\\bar\\bat')
563 tester('ntpath.relpath("/x", "/foo/bar/bat")', '..\\..\\..\\x')
564 tester('ntpath.relpath("/", "/")', '.')
565 tester('ntpath.relpath("/a", "/a")', '.')
566 tester('ntpath.relpath("/a/b", "/a/b")', '.')
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000567 tester('ntpath.relpath("c:/foo", "C:/FOO")', '.')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000568
Serhiy Storchaka38220932015-03-31 15:31:53 +0300569 def test_commonpath(self):
570 def check(paths, expected):
571 tester(('ntpath.commonpath(%r)' % paths).replace('\\\\', '\\'),
572 expected)
573 def check_error(exc, paths):
574 self.assertRaises(exc, ntpath.commonpath, paths)
575 self.assertRaises(exc, ntpath.commonpath,
576 [os.fsencode(p) for p in paths])
577
578 self.assertRaises(ValueError, ntpath.commonpath, [])
579 check_error(ValueError, ['C:\\Program Files', 'Program Files'])
580 check_error(ValueError, ['C:\\Program Files', 'C:Program Files'])
581 check_error(ValueError, ['\\Program Files', 'Program Files'])
582 check_error(ValueError, ['Program Files', 'C:\\Program Files'])
583 check(['C:\\Program Files'], 'C:\\Program Files')
584 check(['C:\\Program Files', 'C:\\Program Files'], 'C:\\Program Files')
585 check(['C:\\Program Files\\', 'C:\\Program Files'],
586 'C:\\Program Files')
587 check(['C:\\Program Files\\', 'C:\\Program Files\\'],
588 'C:\\Program Files')
589 check(['C:\\\\Program Files', 'C:\\Program Files\\\\'],
590 'C:\\Program Files')
591 check(['C:\\.\\Program Files', 'C:\\Program Files\\.'],
592 'C:\\Program Files')
593 check(['C:\\', 'C:\\bin'], 'C:\\')
594 check(['C:\\Program Files', 'C:\\bin'], 'C:\\')
595 check(['C:\\Program Files', 'C:\\Program Files\\Bar'],
596 'C:\\Program Files')
597 check(['C:\\Program Files\\Foo', 'C:\\Program Files\\Bar'],
598 'C:\\Program Files')
599 check(['C:\\Program Files', 'C:\\Projects'], 'C:\\')
600 check(['C:\\Program Files\\', 'C:\\Projects'], 'C:\\')
601
602 check(['C:\\Program Files\\Foo', 'C:/Program Files/Bar'],
603 'C:\\Program Files')
604 check(['C:\\Program Files\\Foo', 'c:/program files/bar'],
605 'C:\\Program Files')
606 check(['c:/program files/bar', 'C:\\Program Files\\Foo'],
607 'c:\\program files')
608
609 check_error(ValueError, ['C:\\Program Files', 'D:\\Program Files'])
610
611 check(['spam'], 'spam')
612 check(['spam', 'spam'], 'spam')
613 check(['spam', 'alot'], '')
614 check(['and\\jam', 'and\\spam'], 'and')
615 check(['and\\\\jam', 'and\\spam\\\\'], 'and')
616 check(['and\\.\\jam', '.\\and\\spam'], 'and')
617 check(['and\\jam', 'and\\spam', 'alot'], '')
618 check(['and\\jam', 'and\\spam', 'and'], 'and')
619 check(['C:and\\jam', 'C:and\\spam'], 'C:and')
620
621 check([''], '')
622 check(['', 'spam\\alot'], '')
623 check_error(ValueError, ['', '\\spam\\alot'])
624
625 self.assertRaises(TypeError, ntpath.commonpath,
626 [b'C:\\Program Files', 'C:\\Program Files\\Foo'])
627 self.assertRaises(TypeError, ntpath.commonpath,
628 [b'C:\\Program Files', 'Program Files\\Foo'])
629 self.assertRaises(TypeError, ntpath.commonpath,
630 [b'Program Files', 'C:\\Program Files\\Foo'])
631 self.assertRaises(TypeError, ntpath.commonpath,
632 ['C:\\Program Files', b'C:\\Program Files\\Foo'])
633 self.assertRaises(TypeError, ntpath.commonpath,
634 ['C:\\Program Files', b'Program Files\\Foo'])
635 self.assertRaises(TypeError, ntpath.commonpath,
636 ['Program Files', b'C:\\Program Files\\Foo'])
637
Brian Curtin62857742010-09-06 17:07:27 +0000638 def test_sameopenfile(self):
639 with TemporaryFile() as tf1, TemporaryFile() as tf2:
640 # Make sure the same file is really the same
641 self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
642 # Make sure different files are really different
643 self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
Brian Curtin13a0db52010-09-06 19:46:17 +0000644 # Make sure invalid values don't cause issues on win32
645 if sys.platform == "win32":
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +0000646 with self.assertRaises(OSError):
Brian Curtin13a0db52010-09-06 19:46:17 +0000647 # Invalid file descriptors shouldn't display assert
648 # dialogs (#4804)
649 ntpath.sameopenfile(-1, -1)
Brian Curtin62857742010-09-06 17:07:27 +0000650
Tim Golden6b528062013-08-01 12:44:00 +0100651 def test_ismount(self):
652 self.assertTrue(ntpath.ismount("c:\\"))
653 self.assertTrue(ntpath.ismount("C:\\"))
654 self.assertTrue(ntpath.ismount("c:/"))
655 self.assertTrue(ntpath.ismount("C:/"))
656 self.assertTrue(ntpath.ismount("\\\\.\\c:\\"))
657 self.assertTrue(ntpath.ismount("\\\\.\\C:\\"))
658
659 self.assertTrue(ntpath.ismount(b"c:\\"))
660 self.assertTrue(ntpath.ismount(b"C:\\"))
661 self.assertTrue(ntpath.ismount(b"c:/"))
662 self.assertTrue(ntpath.ismount(b"C:/"))
663 self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\"))
664 self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\"))
665
Hai Shi46605972020-08-04 00:49:18 +0800666 with os_helper.temp_dir() as d:
Tim Golden6b528062013-08-01 12:44:00 +0100667 self.assertFalse(ntpath.ismount(d))
668
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100669 if sys.platform == "win32":
670 #
671 # Make sure the current folder isn't the root folder
672 # (or any other volume root). The drive-relative
673 # locations below cannot then refer to mount points
674 #
675 drive, path = ntpath.splitdrive(sys.executable)
Hai Shi598a9512020-08-07 23:18:38 +0800676 with os_helper.change_cwd(ntpath.dirname(sys.executable)):
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100677 self.assertFalse(ntpath.ismount(drive.lower()))
678 self.assertFalse(ntpath.ismount(drive.upper()))
Tim Golden6b528062013-08-01 12:44:00 +0100679
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100680 self.assertTrue(ntpath.ismount("\\\\localhost\\c$"))
681 self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\"))
Tim Golden6b528062013-08-01 12:44:00 +0100682
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100683 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$"))
684 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\"))
Christian Heimesf6cd9672008-03-26 13:45:42 +0000685
Tim Goldenff64add2018-07-25 14:36:54 +0100686 def assertEqualCI(self, s1, s2):
687 """Assert that two strings are equal ignoring case differences."""
688 self.assertEqual(s1.lower(), s2.lower())
689
Steve Dower23ad6d02018-02-22 10:39:10 -0800690 @unittest.skipUnless(nt, "OS helpers require 'nt' module")
691 def test_nt_helpers(self):
692 # Trivial validation that the helpers do not break, and support both
693 # unicode and bytes (UTF-8) paths
694
Tim Goldenff64add2018-07-25 14:36:54 +0100695 executable = nt._getfinalpathname(sys.executable)
696
697 for path in executable, os.fsencode(executable):
698 volume_path = nt._getvolumepathname(path)
699 path_drive = ntpath.splitdrive(path)[0]
700 volume_path_drive = ntpath.splitdrive(volume_path)[0]
701 self.assertEqualCI(path_drive, volume_path_drive)
Steve Dower23ad6d02018-02-22 10:39:10 -0800702
703 cap, free = nt._getdiskusage(sys.exec_prefix)
704 self.assertGreater(cap, 0)
705 self.assertGreater(free, 0)
706 b_cap, b_free = nt._getdiskusage(sys.exec_prefix.encode())
707 # Free space may change, so only test the capacity is equal
708 self.assertEqual(b_cap, cap)
709 self.assertGreater(b_free, 0)
710
711 for path in [sys.prefix, sys.executable]:
712 final_path = nt._getfinalpathname(path)
713 self.assertIsInstance(final_path, str)
714 self.assertGreater(len(final_path), 0)
715
716 b_final_path = nt._getfinalpathname(path.encode())
717 self.assertIsInstance(b_final_path, bytes)
718 self.assertGreater(len(b_final_path), 0)
719
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200720class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000721 pathmodule = ntpath
Serhiy Storchaka9ed707e2017-01-13 20:55:05 +0200722 attributes = ['relpath']
Florent Xiclunac9c79782010-03-08 12:24:53 +0000723
724
Steve Dower97d79062019-09-10 14:52:48 +0100725class PathLikeTests(NtpathTestCase):
Brett Cannon3f9183b2016-08-26 14:44:48 -0700726
727 path = ntpath
728
Brett Cannon3f9183b2016-08-26 14:44:48 -0700729 def setUp(self):
Hai Shi46605972020-08-04 00:49:18 +0800730 self.file_name = os_helper.TESTFN
731 self.file_path = FakePath(os_helper.TESTFN)
732 self.addCleanup(os_helper.unlink, self.file_name)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700733 with open(self.file_name, 'xb', 0) as file:
734 file.write(b"test_ntpath.PathLikeTests")
735
Steve Dower97d79062019-09-10 14:52:48 +0100736 def _check_function(self, func):
737 self.assertPathEqual(func(self.file_path), func(self.file_name))
Brett Cannon3f9183b2016-08-26 14:44:48 -0700738
739 def test_path_normcase(self):
Steve Dower97d79062019-09-10 14:52:48 +0100740 self._check_function(self.path.normcase)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700741
742 def test_path_isabs(self):
Steve Dower97d79062019-09-10 14:52:48 +0100743 self._check_function(self.path.isabs)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700744
745 def test_path_join(self):
Serhiy Storchakab21d1552018-03-02 11:53:51 +0200746 self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
Brett Cannon3f9183b2016-08-26 14:44:48 -0700747 self.path.join('a', 'b', 'c'))
748
749 def test_path_split(self):
Steve Dower97d79062019-09-10 14:52:48 +0100750 self._check_function(self.path.split)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700751
752 def test_path_splitext(self):
Steve Dower97d79062019-09-10 14:52:48 +0100753 self._check_function(self.path.splitext)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700754
755 def test_path_splitdrive(self):
Steve Dower97d79062019-09-10 14:52:48 +0100756 self._check_function(self.path.splitdrive)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700757
758 def test_path_basename(self):
Steve Dower97d79062019-09-10 14:52:48 +0100759 self._check_function(self.path.basename)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700760
761 def test_path_dirname(self):
Steve Dower97d79062019-09-10 14:52:48 +0100762 self._check_function(self.path.dirname)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700763
764 def test_path_islink(self):
Steve Dower97d79062019-09-10 14:52:48 +0100765 self._check_function(self.path.islink)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700766
767 def test_path_lexists(self):
Steve Dower97d79062019-09-10 14:52:48 +0100768 self._check_function(self.path.lexists)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700769
770 def test_path_ismount(self):
Steve Dower97d79062019-09-10 14:52:48 +0100771 self._check_function(self.path.ismount)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700772
773 def test_path_expanduser(self):
Steve Dower97d79062019-09-10 14:52:48 +0100774 self._check_function(self.path.expanduser)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700775
776 def test_path_expandvars(self):
Steve Dower97d79062019-09-10 14:52:48 +0100777 self._check_function(self.path.expandvars)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700778
779 def test_path_normpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100780 self._check_function(self.path.normpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700781
782 def test_path_abspath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100783 self._check_function(self.path.abspath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700784
785 def test_path_realpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100786 self._check_function(self.path.realpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700787
788 def test_path_relpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100789 self._check_function(self.path.relpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700790
791 def test_path_commonpath(self):
792 common_path = self.path.commonpath([self.file_path, self.file_name])
Steve Dower97d79062019-09-10 14:52:48 +0100793 self.assertPathEqual(common_path, self.file_name)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700794
795 def test_path_isdir(self):
Steve Dower97d79062019-09-10 14:52:48 +0100796 self._check_function(self.path.isdir)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700797
798
Christian Heimesf6cd9672008-03-26 13:45:42 +0000799if __name__ == "__main__":
800 unittest.main()