blob: f97aca5f94f579facc0e3806a1623203599953a9 [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
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300506 env['HOMEDRIVE'] = 'C:\\'
Barney Gale3f3d82b2021-04-07 23:50:13 +0100507 env['HOMEPATH'] = 'Users\\eric'
508 env['USERNAME'] = 'eric'
509 tester('ntpath.expanduser("~test")', 'C:\\Users\\test')
510 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300511
512 del env['HOMEDRIVE']
Barney Gale3f3d82b2021-04-07 23:50:13 +0100513 tester('ntpath.expanduser("~test")', 'Users\\test')
514 tester('ntpath.expanduser("~")', 'Users\\eric')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300515
516 env.clear()
Barney Gale3f3d82b2021-04-07 23:50:13 +0100517 env['USERPROFILE'] = 'C:\\Users\\eric'
518 env['USERNAME'] = 'eric'
519 tester('ntpath.expanduser("~test")', 'C:\\Users\\test')
520 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300521 tester('ntpath.expanduser("~test\\foo\\bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100522 'C:\\Users\\test\\foo\\bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300523 tester('ntpath.expanduser("~test/foo/bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100524 'C:\\Users\\test/foo/bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300525 tester('ntpath.expanduser("~\\foo\\bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100526 'C:\\Users\\eric\\foo\\bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300527 tester('ntpath.expanduser("~/foo/bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100528 'C:\\Users\\eric/foo/bar')
Anthony Sottile25ec4a42019-03-12 08:39:57 -0700529
530 # bpo-36264: ignore `HOME` when set on windows
531 env.clear()
532 env['HOME'] = 'F:\\'
Barney Gale3f3d82b2021-04-07 23:50:13 +0100533 env['USERPROFILE'] = 'C:\\Users\\eric'
534 env['USERNAME'] = 'eric'
535 tester('ntpath.expanduser("~test")', 'C:\\Users\\test')
536 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
537
538 # bpo-39899: don't guess another user's home directory if
539 # `%USERNAME% != basename(%USERPROFILE%)`
540 env.clear()
541 env['USERPROFILE'] = 'C:\\Users\\eric'
542 env['USERNAME'] = 'idle'
543 tester('ntpath.expanduser("~test")', '~test')
544 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
545
546
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300547
Steve Dower23ad6d02018-02-22 10:39:10 -0800548 @unittest.skipUnless(nt, "abspath requires 'nt' module")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000549 def test_abspath(self):
Steve Dower23ad6d02018-02-22 10:39:10 -0800550 tester('ntpath.abspath("C:\\")', "C:\\")
Hai Shi46605972020-08-04 00:49:18 +0800551 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047
Franz Wöllertd2e902e2018-07-29 14:47:09 +0200552 tester('ntpath.abspath("")', cwd_dir)
553 tester('ntpath.abspath(" ")', cwd_dir + "\\ ")
554 tester('ntpath.abspath("?")', cwd_dir + "\\?")
Tim Grahamd03b7752018-10-25 11:26:38 -0400555 drive, _ = ntpath.splitdrive(cwd_dir)
556 tester('ntpath.abspath("/abc/")', drive + "\\abc")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000557
558 def test_relpath(self):
Christian Heimesf6cd9672008-03-26 13:45:42 +0000559 tester('ntpath.relpath("a")', 'a')
Steve Dower75e06492019-08-21 13:43:06 -0700560 tester('ntpath.relpath(ntpath.abspath("a"))', 'a')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000561 tester('ntpath.relpath("a/b")', 'a\\b')
562 tester('ntpath.relpath("../a/b")', '..\\a\\b')
Hai Shi46605972020-08-04 00:49:18 +0800563 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir:
Steve Dower75e06492019-08-21 13:43:06 -0700564 currentdir = ntpath.basename(cwd_dir)
Serhiy Storchaka5106d042015-01-26 10:26:14 +0200565 tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a')
566 tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000567 tester('ntpath.relpath("a", "b/c")', '..\\..\\a')
Mark Hammond5a607a32009-05-06 08:04:54 +0000568 tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000569 tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a')
570 tester('ntpath.relpath("a", "a")', '.')
Mark Hammond5a607a32009-05-06 08:04:54 +0000571 tester('ntpath.relpath("/foo/bar/bat", "/x/y/z")', '..\\..\\..\\foo\\bar\\bat')
572 tester('ntpath.relpath("/foo/bar/bat", "/foo/bar")', 'bat')
573 tester('ntpath.relpath("/foo/bar/bat", "/")', 'foo\\bar\\bat')
574 tester('ntpath.relpath("/", "/foo/bar/bat")', '..\\..\\..')
575 tester('ntpath.relpath("/foo/bar/bat", "/x")', '..\\foo\\bar\\bat')
576 tester('ntpath.relpath("/x", "/foo/bar/bat")', '..\\..\\..\\x')
577 tester('ntpath.relpath("/", "/")', '.')
578 tester('ntpath.relpath("/a", "/a")', '.')
579 tester('ntpath.relpath("/a/b", "/a/b")', '.')
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000580 tester('ntpath.relpath("c:/foo", "C:/FOO")', '.')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000581
Serhiy Storchaka38220932015-03-31 15:31:53 +0300582 def test_commonpath(self):
583 def check(paths, expected):
584 tester(('ntpath.commonpath(%r)' % paths).replace('\\\\', '\\'),
585 expected)
586 def check_error(exc, paths):
587 self.assertRaises(exc, ntpath.commonpath, paths)
588 self.assertRaises(exc, ntpath.commonpath,
589 [os.fsencode(p) for p in paths])
590
591 self.assertRaises(ValueError, ntpath.commonpath, [])
592 check_error(ValueError, ['C:\\Program Files', 'Program Files'])
593 check_error(ValueError, ['C:\\Program Files', 'C:Program Files'])
594 check_error(ValueError, ['\\Program Files', 'Program Files'])
595 check_error(ValueError, ['Program Files', 'C:\\Program Files'])
596 check(['C:\\Program Files'], 'C:\\Program Files')
597 check(['C:\\Program Files', 'C:\\Program Files'], 'C:\\Program Files')
598 check(['C:\\Program Files\\', 'C:\\Program Files'],
599 'C:\\Program Files')
600 check(['C:\\Program Files\\', 'C:\\Program Files\\'],
601 'C:\\Program Files')
602 check(['C:\\\\Program Files', 'C:\\Program Files\\\\'],
603 'C:\\Program Files')
604 check(['C:\\.\\Program Files', 'C:\\Program Files\\.'],
605 'C:\\Program Files')
606 check(['C:\\', 'C:\\bin'], 'C:\\')
607 check(['C:\\Program Files', 'C:\\bin'], 'C:\\')
608 check(['C:\\Program Files', 'C:\\Program Files\\Bar'],
609 'C:\\Program Files')
610 check(['C:\\Program Files\\Foo', 'C:\\Program Files\\Bar'],
611 'C:\\Program Files')
612 check(['C:\\Program Files', 'C:\\Projects'], 'C:\\')
613 check(['C:\\Program Files\\', 'C:\\Projects'], 'C:\\')
614
615 check(['C:\\Program Files\\Foo', 'C:/Program Files/Bar'],
616 'C:\\Program Files')
617 check(['C:\\Program Files\\Foo', 'c:/program files/bar'],
618 'C:\\Program Files')
619 check(['c:/program files/bar', 'C:\\Program Files\\Foo'],
620 'c:\\program files')
621
622 check_error(ValueError, ['C:\\Program Files', 'D:\\Program Files'])
623
624 check(['spam'], 'spam')
625 check(['spam', 'spam'], 'spam')
626 check(['spam', 'alot'], '')
627 check(['and\\jam', 'and\\spam'], 'and')
628 check(['and\\\\jam', 'and\\spam\\\\'], 'and')
629 check(['and\\.\\jam', '.\\and\\spam'], 'and')
630 check(['and\\jam', 'and\\spam', 'alot'], '')
631 check(['and\\jam', 'and\\spam', 'and'], 'and')
632 check(['C:and\\jam', 'C:and\\spam'], 'C:and')
633
634 check([''], '')
635 check(['', 'spam\\alot'], '')
636 check_error(ValueError, ['', '\\spam\\alot'])
637
638 self.assertRaises(TypeError, ntpath.commonpath,
639 [b'C:\\Program Files', 'C:\\Program Files\\Foo'])
640 self.assertRaises(TypeError, ntpath.commonpath,
641 [b'C:\\Program Files', 'Program Files\\Foo'])
642 self.assertRaises(TypeError, ntpath.commonpath,
643 [b'Program Files', 'C:\\Program Files\\Foo'])
644 self.assertRaises(TypeError, ntpath.commonpath,
645 ['C:\\Program Files', b'C:\\Program Files\\Foo'])
646 self.assertRaises(TypeError, ntpath.commonpath,
647 ['C:\\Program Files', b'Program Files\\Foo'])
648 self.assertRaises(TypeError, ntpath.commonpath,
649 ['Program Files', b'C:\\Program Files\\Foo'])
650
Brian Curtin62857742010-09-06 17:07:27 +0000651 def test_sameopenfile(self):
652 with TemporaryFile() as tf1, TemporaryFile() as tf2:
653 # Make sure the same file is really the same
654 self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
655 # Make sure different files are really different
656 self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
Brian Curtin13a0db52010-09-06 19:46:17 +0000657 # Make sure invalid values don't cause issues on win32
658 if sys.platform == "win32":
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +0000659 with self.assertRaises(OSError):
Brian Curtin13a0db52010-09-06 19:46:17 +0000660 # Invalid file descriptors shouldn't display assert
661 # dialogs (#4804)
662 ntpath.sameopenfile(-1, -1)
Brian Curtin62857742010-09-06 17:07:27 +0000663
Tim Golden6b528062013-08-01 12:44:00 +0100664 def test_ismount(self):
665 self.assertTrue(ntpath.ismount("c:\\"))
666 self.assertTrue(ntpath.ismount("C:\\"))
667 self.assertTrue(ntpath.ismount("c:/"))
668 self.assertTrue(ntpath.ismount("C:/"))
669 self.assertTrue(ntpath.ismount("\\\\.\\c:\\"))
670 self.assertTrue(ntpath.ismount("\\\\.\\C:\\"))
671
672 self.assertTrue(ntpath.ismount(b"c:\\"))
673 self.assertTrue(ntpath.ismount(b"C:\\"))
674 self.assertTrue(ntpath.ismount(b"c:/"))
675 self.assertTrue(ntpath.ismount(b"C:/"))
676 self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\"))
677 self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\"))
678
Hai Shi46605972020-08-04 00:49:18 +0800679 with os_helper.temp_dir() as d:
Tim Golden6b528062013-08-01 12:44:00 +0100680 self.assertFalse(ntpath.ismount(d))
681
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100682 if sys.platform == "win32":
683 #
684 # Make sure the current folder isn't the root folder
685 # (or any other volume root). The drive-relative
686 # locations below cannot then refer to mount points
687 #
688 drive, path = ntpath.splitdrive(sys.executable)
Hai Shi598a9512020-08-07 23:18:38 +0800689 with os_helper.change_cwd(ntpath.dirname(sys.executable)):
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100690 self.assertFalse(ntpath.ismount(drive.lower()))
691 self.assertFalse(ntpath.ismount(drive.upper()))
Tim Golden6b528062013-08-01 12:44:00 +0100692
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100693 self.assertTrue(ntpath.ismount("\\\\localhost\\c$"))
694 self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\"))
Tim Golden6b528062013-08-01 12:44:00 +0100695
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100696 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$"))
697 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\"))
Christian Heimesf6cd9672008-03-26 13:45:42 +0000698
Tim Goldenff64add2018-07-25 14:36:54 +0100699 def assertEqualCI(self, s1, s2):
700 """Assert that two strings are equal ignoring case differences."""
701 self.assertEqual(s1.lower(), s2.lower())
702
Steve Dower23ad6d02018-02-22 10:39:10 -0800703 @unittest.skipUnless(nt, "OS helpers require 'nt' module")
704 def test_nt_helpers(self):
705 # Trivial validation that the helpers do not break, and support both
706 # unicode and bytes (UTF-8) paths
707
Tim Goldenff64add2018-07-25 14:36:54 +0100708 executable = nt._getfinalpathname(sys.executable)
709
710 for path in executable, os.fsencode(executable):
711 volume_path = nt._getvolumepathname(path)
712 path_drive = ntpath.splitdrive(path)[0]
713 volume_path_drive = ntpath.splitdrive(volume_path)[0]
714 self.assertEqualCI(path_drive, volume_path_drive)
Steve Dower23ad6d02018-02-22 10:39:10 -0800715
716 cap, free = nt._getdiskusage(sys.exec_prefix)
717 self.assertGreater(cap, 0)
718 self.assertGreater(free, 0)
719 b_cap, b_free = nt._getdiskusage(sys.exec_prefix.encode())
720 # Free space may change, so only test the capacity is equal
721 self.assertEqual(b_cap, cap)
722 self.assertGreater(b_free, 0)
723
724 for path in [sys.prefix, sys.executable]:
725 final_path = nt._getfinalpathname(path)
726 self.assertIsInstance(final_path, str)
727 self.assertGreater(len(final_path), 0)
728
729 b_final_path = nt._getfinalpathname(path.encode())
730 self.assertIsInstance(b_final_path, bytes)
731 self.assertGreater(len(b_final_path), 0)
732
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200733class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000734 pathmodule = ntpath
Serhiy Storchaka9ed707e2017-01-13 20:55:05 +0200735 attributes = ['relpath']
Florent Xiclunac9c79782010-03-08 12:24:53 +0000736
737
Steve Dower97d79062019-09-10 14:52:48 +0100738class PathLikeTests(NtpathTestCase):
Brett Cannon3f9183b2016-08-26 14:44:48 -0700739
740 path = ntpath
741
Brett Cannon3f9183b2016-08-26 14:44:48 -0700742 def setUp(self):
Hai Shi46605972020-08-04 00:49:18 +0800743 self.file_name = os_helper.TESTFN
744 self.file_path = FakePath(os_helper.TESTFN)
745 self.addCleanup(os_helper.unlink, self.file_name)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700746 with open(self.file_name, 'xb', 0) as file:
747 file.write(b"test_ntpath.PathLikeTests")
748
Steve Dower97d79062019-09-10 14:52:48 +0100749 def _check_function(self, func):
750 self.assertPathEqual(func(self.file_path), func(self.file_name))
Brett Cannon3f9183b2016-08-26 14:44:48 -0700751
752 def test_path_normcase(self):
Steve Dower97d79062019-09-10 14:52:48 +0100753 self._check_function(self.path.normcase)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700754
755 def test_path_isabs(self):
Steve Dower97d79062019-09-10 14:52:48 +0100756 self._check_function(self.path.isabs)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700757
758 def test_path_join(self):
Serhiy Storchakab21d1552018-03-02 11:53:51 +0200759 self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
Brett Cannon3f9183b2016-08-26 14:44:48 -0700760 self.path.join('a', 'b', 'c'))
761
762 def test_path_split(self):
Steve Dower97d79062019-09-10 14:52:48 +0100763 self._check_function(self.path.split)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700764
765 def test_path_splitext(self):
Steve Dower97d79062019-09-10 14:52:48 +0100766 self._check_function(self.path.splitext)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700767
768 def test_path_splitdrive(self):
Steve Dower97d79062019-09-10 14:52:48 +0100769 self._check_function(self.path.splitdrive)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700770
771 def test_path_basename(self):
Steve Dower97d79062019-09-10 14:52:48 +0100772 self._check_function(self.path.basename)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700773
774 def test_path_dirname(self):
Steve Dower97d79062019-09-10 14:52:48 +0100775 self._check_function(self.path.dirname)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700776
777 def test_path_islink(self):
Steve Dower97d79062019-09-10 14:52:48 +0100778 self._check_function(self.path.islink)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700779
780 def test_path_lexists(self):
Steve Dower97d79062019-09-10 14:52:48 +0100781 self._check_function(self.path.lexists)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700782
783 def test_path_ismount(self):
Steve Dower97d79062019-09-10 14:52:48 +0100784 self._check_function(self.path.ismount)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700785
786 def test_path_expanduser(self):
Steve Dower97d79062019-09-10 14:52:48 +0100787 self._check_function(self.path.expanduser)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700788
789 def test_path_expandvars(self):
Steve Dower97d79062019-09-10 14:52:48 +0100790 self._check_function(self.path.expandvars)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700791
792 def test_path_normpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100793 self._check_function(self.path.normpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700794
795 def test_path_abspath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100796 self._check_function(self.path.abspath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700797
798 def test_path_realpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100799 self._check_function(self.path.realpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700800
801 def test_path_relpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100802 self._check_function(self.path.relpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700803
804 def test_path_commonpath(self):
805 common_path = self.path.commonpath([self.file_path, self.file_name])
Steve Dower97d79062019-09-10 14:52:48 +0100806 self.assertPathEqual(common_path, self.file_name)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700807
808 def test_path_isdir(self):
Steve Dower97d79062019-09-10 14:52:48 +0100809 self._check_function(self.path.isdir)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700810
811
Christian Heimesf6cd9672008-03-26 13:45:42 +0000812if __name__ == "__main__":
813 unittest.main()