blob: 661c59d6171635642fb25c649f253b0103216ada [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')
Barney Galebaecfbd2021-04-28 16:50:17 +0100274 def test_realpath_strict(self):
275 # Bug #43757: raise FileNotFoundError in strict mode if we encounter
276 # a path that does not exist.
277 ABSTFN = ntpath.abspath(os_helper.TESTFN)
278 os.symlink(ABSTFN + "1", ABSTFN)
279 self.addCleanup(os_helper.unlink, ABSTFN)
280 self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, strict=True)
281 self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", strict=True)
282
283 @os_helper.skip_unless_symlink
284 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
Steve Dower75e06492019-08-21 13:43:06 -0700285 def test_realpath_relative(self):
Hai Shi46605972020-08-04 00:49:18 +0800286 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700287 open(ABSTFN, "wb").close()
Hai Shi46605972020-08-04 00:49:18 +0800288 self.addCleanup(os_helper.unlink, ABSTFN)
289 self.addCleanup(os_helper.unlink, ABSTFN + "1")
Steve Dower75e06492019-08-21 13:43:06 -0700290
291 os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1"))
Steve Dower97d79062019-09-10 14:52:48 +0100292 self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700293
Hai Shi46605972020-08-04 00:49:18 +0800294 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700295 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
296 def test_realpath_broken_symlinks(self):
Hai Shi46605972020-08-04 00:49:18 +0800297 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700298 os.mkdir(ABSTFN)
Hai Shi79bb2c92020-08-06 19:51:29 +0800299 self.addCleanup(os_helper.rmtree, ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700300
Hai Shi598a9512020-08-07 23:18:38 +0800301 with os_helper.change_cwd(ABSTFN):
Steve Dower75e06492019-08-21 13:43:06 -0700302 os.mkdir("subdir")
303 os.chdir("subdir")
304 os.symlink(".", "recursive")
305 os.symlink("..", "parent")
306 os.chdir("..")
307 os.symlink(".", "self")
308 os.symlink("missing", "broken")
309 os.symlink(r"broken\bar", "broken1")
310 os.symlink(r"self\self\broken", "broken2")
311 os.symlink(r"subdir\parent\subdir\parent\broken", "broken3")
312 os.symlink(ABSTFN + r"\broken", "broken4")
313 os.symlink(r"recursive\..\broken", "broken5")
314
Steve Dower97d79062019-09-10 14:52:48 +0100315 self.assertPathEqual(ntpath.realpath("broken"),
316 ABSTFN + r"\missing")
317 self.assertPathEqual(ntpath.realpath(r"broken\foo"),
318 ABSTFN + r"\missing\foo")
Steve Dowerabde52c2019-11-15 09:49:21 -0800319 # bpo-38453: We no longer recursively resolve segments of relative
320 # symlinks that the OS cannot resolve.
Steve Dower97d79062019-09-10 14:52:48 +0100321 self.assertPathEqual(ntpath.realpath(r"broken1"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800322 ABSTFN + r"\broken\bar")
Steve Dower97d79062019-09-10 14:52:48 +0100323 self.assertPathEqual(ntpath.realpath(r"broken1\baz"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800324 ABSTFN + r"\broken\bar\baz")
Steve Dower97d79062019-09-10 14:52:48 +0100325 self.assertPathEqual(ntpath.realpath("broken2"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800326 ABSTFN + r"\self\self\missing")
Steve Dower97d79062019-09-10 14:52:48 +0100327 self.assertPathEqual(ntpath.realpath("broken3"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800328 ABSTFN + r"\subdir\parent\subdir\parent\missing")
Steve Dower97d79062019-09-10 14:52:48 +0100329 self.assertPathEqual(ntpath.realpath("broken4"),
330 ABSTFN + r"\missing")
331 self.assertPathEqual(ntpath.realpath("broken5"),
332 ABSTFN + r"\missing")
Steve Dower75e06492019-08-21 13:43:06 -0700333
Steve Dower97d79062019-09-10 14:52:48 +0100334 self.assertPathEqual(ntpath.realpath(b"broken"),
335 os.fsencode(ABSTFN + r"\missing"))
336 self.assertPathEqual(ntpath.realpath(rb"broken\foo"),
337 os.fsencode(ABSTFN + r"\missing\foo"))
338 self.assertPathEqual(ntpath.realpath(rb"broken1"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800339 os.fsencode(ABSTFN + r"\broken\bar"))
Steve Dower97d79062019-09-10 14:52:48 +0100340 self.assertPathEqual(ntpath.realpath(rb"broken1\baz"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800341 os.fsencode(ABSTFN + r"\broken\bar\baz"))
Steve Dower97d79062019-09-10 14:52:48 +0100342 self.assertPathEqual(ntpath.realpath(b"broken2"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800343 os.fsencode(ABSTFN + r"\self\self\missing"))
Steve Dower97d79062019-09-10 14:52:48 +0100344 self.assertPathEqual(ntpath.realpath(rb"broken3"),
Steve Dowerabde52c2019-11-15 09:49:21 -0800345 os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing"))
Steve Dower97d79062019-09-10 14:52:48 +0100346 self.assertPathEqual(ntpath.realpath(b"broken4"),
347 os.fsencode(ABSTFN + r"\missing"))
348 self.assertPathEqual(ntpath.realpath(b"broken5"),
349 os.fsencode(ABSTFN + r"\missing"))
Steve Dower75e06492019-08-21 13:43:06 -0700350
Hai Shi46605972020-08-04 00:49:18 +0800351 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700352 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
353 def test_realpath_symlink_loops(self):
Barney Galebaecfbd2021-04-28 16:50:17 +0100354 # Symlink loops in non-strict mode are non-deterministic as to which
355 # path is returned, but it will always be the fully resolved path of
356 # one member of the cycle
Hai Shi46605972020-08-04 00:49:18 +0800357 ABSTFN = ntpath.abspath(os_helper.TESTFN)
358 self.addCleanup(os_helper.unlink, ABSTFN)
359 self.addCleanup(os_helper.unlink, ABSTFN + "1")
360 self.addCleanup(os_helper.unlink, ABSTFN + "2")
361 self.addCleanup(os_helper.unlink, ABSTFN + "y")
362 self.addCleanup(os_helper.unlink, ABSTFN + "c")
363 self.addCleanup(os_helper.unlink, ABSTFN + "a")
Steve Dower75e06492019-08-21 13:43:06 -0700364
Steve Dower75e06492019-08-21 13:43:06 -0700365 os.symlink(ABSTFN, ABSTFN)
Steve Dowera0e3d272019-10-03 08:31:03 -0700366 self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700367
Steve Dower75e06492019-08-21 13:43:06 -0700368 os.symlink(ABSTFN + "1", ABSTFN + "2")
369 os.symlink(ABSTFN + "2", ABSTFN + "1")
Steve Dowera0e3d272019-10-03 08:31:03 -0700370 expected = (ABSTFN + "1", ABSTFN + "2")
Steve Dower97d79062019-09-10 14:52:48 +0100371 self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected)
372 self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected)
Steve Dower75e06492019-08-21 13:43:06 -0700373
Steve Dower97d79062019-09-10 14:52:48 +0100374 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\x"),
375 (ntpath.join(r, "x") for r in expected))
376 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."),
377 ntpath.dirname(ABSTFN))
378 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
379 ntpath.dirname(ABSTFN) + "\\x")
Steve Dower75e06492019-08-21 13:43:06 -0700380 os.symlink(ABSTFN + "x", ABSTFN + "y")
Steve Dower97d79062019-09-10 14:52:48 +0100381 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\"
382 + ntpath.basename(ABSTFN) + "y"),
383 ABSTFN + "x")
384 self.assertPathIn(ntpath.realpath(ABSTFN + "1\\..\\"
385 + ntpath.basename(ABSTFN) + "1"),
386 expected)
Steve Dower75e06492019-08-21 13:43:06 -0700387
388 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
Steve Dowera0e3d272019-10-03 08:31:03 -0700389 self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), ABSTFN + "a")
Steve Dower75e06492019-08-21 13:43:06 -0700390
391 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
392 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
Steve Dowera0e3d272019-10-03 08:31:03 -0700393 self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), ABSTFN + "c")
Steve Dower75e06492019-08-21 13:43:06 -0700394
395 # Test using relative path as well.
Steve Dowera0e3d272019-10-03 08:31:03 -0700396 self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN)
Steve Dower75e06492019-08-21 13:43:06 -0700397
Hai Shi46605972020-08-04 00:49:18 +0800398 @os_helper.skip_unless_symlink
Steve Dower75e06492019-08-21 13:43:06 -0700399 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
Barney Galebaecfbd2021-04-28 16:50:17 +0100400 def test_realpath_symlink_loops_strict(self):
401 # Symlink loops raise OSError in strict mode
402 ABSTFN = ntpath.abspath(os_helper.TESTFN)
403 self.addCleanup(os_helper.unlink, ABSTFN)
404 self.addCleanup(os_helper.unlink, ABSTFN + "1")
405 self.addCleanup(os_helper.unlink, ABSTFN + "2")
406 self.addCleanup(os_helper.unlink, ABSTFN + "y")
407 self.addCleanup(os_helper.unlink, ABSTFN + "c")
408 self.addCleanup(os_helper.unlink, ABSTFN + "a")
409
410 os.symlink(ABSTFN, ABSTFN)
411 self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=True)
412
413 os.symlink(ABSTFN + "1", ABSTFN + "2")
414 os.symlink(ABSTFN + "2", ABSTFN + "1")
415 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=True)
416 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=True)
417 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", strict=True)
418 # Windows eliminates '..' components before resolving links, so the
419 # following call is not expected to raise.
420 self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..", strict=True),
421 ntpath.dirname(ABSTFN))
422 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\x", strict=True)
423 os.symlink(ABSTFN + "x", ABSTFN + "y")
424 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\"
425 + ntpath.basename(ABSTFN) + "y",
426 strict=True)
427 self.assertRaises(OSError, ntpath.realpath,
428 ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1",
429 strict=True)
430
431 os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
432 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=True)
433
434 os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
435 + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
436 self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=True)
437
438 # Test using relative path as well.
439 self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN),
440 strict=True)
441
442 @os_helper.skip_unless_symlink
443 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
Steve Dower75e06492019-08-21 13:43:06 -0700444 def test_realpath_symlink_prefix(self):
Hai Shi46605972020-08-04 00:49:18 +0800445 ABSTFN = ntpath.abspath(os_helper.TESTFN)
446 self.addCleanup(os_helper.unlink, ABSTFN + "3")
447 self.addCleanup(os_helper.unlink, "\\\\?\\" + ABSTFN + "3.")
448 self.addCleanup(os_helper.unlink, ABSTFN + "3link")
449 self.addCleanup(os_helper.unlink, ABSTFN + "3.link")
Steve Dower75e06492019-08-21 13:43:06 -0700450
451 with open(ABSTFN + "3", "wb") as f:
452 f.write(b'0')
453 os.symlink(ABSTFN + "3", ABSTFN + "3link")
454
455 with open("\\\\?\\" + ABSTFN + "3.", "wb") as f:
456 f.write(b'1')
457 os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link")
458
Steve Dower97d79062019-09-10 14:52:48 +0100459 self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"),
460 ABSTFN + "3")
461 self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"),
462 "\\\\?\\" + ABSTFN + "3.")
Steve Dower75e06492019-08-21 13:43:06 -0700463
464 # Resolved paths should be usable to open target files
465 with open(ntpath.realpath(ABSTFN + "3link"), "rb") as f:
466 self.assertEqual(f.read(), b'0')
467 with open(ntpath.realpath(ABSTFN + "3.link"), "rb") as f:
468 self.assertEqual(f.read(), b'1')
469
470 # When the prefix is included, it is not stripped
Steve Dower97d79062019-09-10 14:52:48 +0100471 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"),
472 "\\\\?\\" + ABSTFN + "3")
473 self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"),
474 "\\\\?\\" + ABSTFN + "3.")
Steve Dower75e06492019-08-21 13:43:06 -0700475
Steve Dower92521fe2019-09-11 10:48:36 +0100476 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
477 def test_realpath_nul(self):
478 tester("ntpath.realpath('NUL')", r'\\.\NUL')
479
Steve Dowerabde52c2019-11-15 09:49:21 -0800480 @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
Steve Dower7c6130c2019-11-15 16:04:00 -0800481 @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname')
Steve Dowerabde52c2019-11-15 09:49:21 -0800482 def test_realpath_cwd(self):
Hai Shi46605972020-08-04 00:49:18 +0800483 ABSTFN = ntpath.abspath(os_helper.TESTFN)
Steve Dowerabde52c2019-11-15 09:49:21 -0800484
Hai Shi46605972020-08-04 00:49:18 +0800485 os_helper.unlink(ABSTFN)
Hai Shi79bb2c92020-08-06 19:51:29 +0800486 os_helper.rmtree(ABSTFN)
Steve Dowerabde52c2019-11-15 09:49:21 -0800487 os.mkdir(ABSTFN)
Hai Shi79bb2c92020-08-06 19:51:29 +0800488 self.addCleanup(os_helper.rmtree, ABSTFN)
Steve Dowerabde52c2019-11-15 09:49:21 -0800489
490 test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName")
Steve Dower7c6130c2019-11-15 16:04:00 -0800491 os.mkdir(test_dir_long)
492
493 test_dir_short = _getshortpathname(test_dir_long)
Steve Dowerabde52c2019-11-15 09:49:21 -0800494 test_file_long = ntpath.join(test_dir_long, "file.txt")
495 test_file_short = ntpath.join(test_dir_short, "file.txt")
496
Steve Dowerabde52c2019-11-15 09:49:21 -0800497 with open(test_file_long, "wb") as f:
498 f.write(b"content")
499
500 self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short))
501
Hai Shi598a9512020-08-07 23:18:38 +0800502 with os_helper.change_cwd(test_dir_long):
Steve Dowerabde52c2019-11-15 09:49:21 -0800503 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
Hai Shi598a9512020-08-07 23:18:38 +0800504 with os_helper.change_cwd(test_dir_long.lower()):
Steve Dowerabde52c2019-11-15 09:49:21 -0800505 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
Hai Shi598a9512020-08-07 23:18:38 +0800506 with os_helper.change_cwd(test_dir_short):
Steve Dowerabde52c2019-11-15 09:49:21 -0800507 self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
508
Christian Heimesf6cd9672008-03-26 13:45:42 +0000509 def test_expandvars(self):
Hai Shi46605972020-08-04 00:49:18 +0800510 with os_helper.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000511 env.clear()
512 env["foo"] = "bar"
513 env["{foo"] = "baz1"
514 env["{foo}"] = "baz2"
Christian Heimesf6cd9672008-03-26 13:45:42 +0000515 tester('ntpath.expandvars("foo")', "foo")
516 tester('ntpath.expandvars("$foo bar")', "bar bar")
517 tester('ntpath.expandvars("${foo}bar")', "barbar")
518 tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar")
519 tester('ntpath.expandvars("$bar bar")', "$bar bar")
520 tester('ntpath.expandvars("$?bar")', "$?bar")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000521 tester('ntpath.expandvars("$foo}bar")', "bar}bar")
522 tester('ntpath.expandvars("${foo")', "${foo")
523 tester('ntpath.expandvars("${{foo}}")', "baz1}")
524 tester('ntpath.expandvars("$foo$foo")', "barbar")
525 tester('ntpath.expandvars("$bar$bar")', "$bar$bar")
526 tester('ntpath.expandvars("%foo% bar")', "bar bar")
527 tester('ntpath.expandvars("%foo%bar")', "barbar")
528 tester('ntpath.expandvars("%foo%%foo%")', "barbar")
529 tester('ntpath.expandvars("%%foo%%foo%foo%")', "%foo%foobar")
530 tester('ntpath.expandvars("%?bar%")', "%?bar%")
531 tester('ntpath.expandvars("%foo%%bar")', "bar%bar")
532 tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar")
Serhiy Storchaka1b87ae02015-03-25 16:40:15 +0200533 tester('ntpath.expandvars("bar\'%foo%")', "bar\'%foo%")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000534
Hai Shi46605972020-08-04 00:49:18 +0800535 @unittest.skipUnless(os_helper.FS_NONASCII, 'need os_helper.FS_NONASCII')
Serhiy Storchakadbb10192014-02-13 10:13:53 +0200536 def test_expandvars_nonascii(self):
537 def check(value, expected):
538 tester('ntpath.expandvars(%r)' % value, expected)
Hai Shi46605972020-08-04 00:49:18 +0800539 with os_helper.EnvironmentVarGuard() as env:
Serhiy Storchakadbb10192014-02-13 10:13:53 +0200540 env.clear()
Hai Shi46605972020-08-04 00:49:18 +0800541 nonascii = os_helper.FS_NONASCII
Serhiy Storchakadbb10192014-02-13 10:13:53 +0200542 env['spam'] = nonascii
543 env[nonascii] = 'ham' + nonascii
544 check('$spam bar', '%s bar' % nonascii)
545 check('$%s bar' % nonascii, '$%s bar' % nonascii)
546 check('${spam}bar', '%sbar' % nonascii)
547 check('${%s}bar' % nonascii, 'ham%sbar' % nonascii)
548 check('$spam}bar', '%s}bar' % nonascii)
549 check('$%s}bar' % nonascii, '$%s}bar' % nonascii)
550 check('%spam% bar', '%s bar' % nonascii)
551 check('%{}% bar'.format(nonascii), 'ham%s bar' % nonascii)
552 check('%spam%bar', '%sbar' % nonascii)
553 check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii)
554
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300555 def test_expanduser(self):
556 tester('ntpath.expanduser("test")', 'test')
557
Hai Shi46605972020-08-04 00:49:18 +0800558 with os_helper.EnvironmentVarGuard() as env:
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300559 env.clear()
560 tester('ntpath.expanduser("~test")', '~test')
561
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300562 env['HOMEDRIVE'] = 'C:\\'
Barney Gale3f3d82b2021-04-07 23:50:13 +0100563 env['HOMEPATH'] = 'Users\\eric'
564 env['USERNAME'] = 'eric'
565 tester('ntpath.expanduser("~test")', 'C:\\Users\\test')
566 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300567
568 del env['HOMEDRIVE']
Barney Gale3f3d82b2021-04-07 23:50:13 +0100569 tester('ntpath.expanduser("~test")', 'Users\\test')
570 tester('ntpath.expanduser("~")', 'Users\\eric')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300571
572 env.clear()
Barney Gale3f3d82b2021-04-07 23:50:13 +0100573 env['USERPROFILE'] = 'C:\\Users\\eric'
574 env['USERNAME'] = 'eric'
575 tester('ntpath.expanduser("~test")', 'C:\\Users\\test')
576 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300577 tester('ntpath.expanduser("~test\\foo\\bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100578 'C:\\Users\\test\\foo\\bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300579 tester('ntpath.expanduser("~test/foo/bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100580 'C:\\Users\\test/foo/bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300581 tester('ntpath.expanduser("~\\foo\\bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100582 'C:\\Users\\eric\\foo\\bar')
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300583 tester('ntpath.expanduser("~/foo/bar")',
Barney Gale3f3d82b2021-04-07 23:50:13 +0100584 'C:\\Users\\eric/foo/bar')
Anthony Sottile25ec4a42019-03-12 08:39:57 -0700585
586 # bpo-36264: ignore `HOME` when set on windows
587 env.clear()
588 env['HOME'] = 'F:\\'
Barney Gale3f3d82b2021-04-07 23:50:13 +0100589 env['USERPROFILE'] = 'C:\\Users\\eric'
590 env['USERNAME'] = 'eric'
591 tester('ntpath.expanduser("~test")', 'C:\\Users\\test')
592 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
593
594 # bpo-39899: don't guess another user's home directory if
595 # `%USERNAME% != basename(%USERPROFILE%)`
596 env.clear()
597 env['USERPROFILE'] = 'C:\\Users\\eric'
598 env['USERNAME'] = 'idle'
599 tester('ntpath.expanduser("~test")', '~test')
600 tester('ntpath.expanduser("~")', 'C:\\Users\\eric')
601
602
Serhiy Storchakaffc1e6d2014-05-28 18:11:29 +0300603
Steve Dower23ad6d02018-02-22 10:39:10 -0800604 @unittest.skipUnless(nt, "abspath requires 'nt' module")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000605 def test_abspath(self):
Steve Dower23ad6d02018-02-22 10:39:10 -0800606 tester('ntpath.abspath("C:\\")', "C:\\")
Hai Shi46605972020-08-04 00:49:18 +0800607 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047
Franz Wöllertd2e902e2018-07-29 14:47:09 +0200608 tester('ntpath.abspath("")', cwd_dir)
609 tester('ntpath.abspath(" ")', cwd_dir + "\\ ")
610 tester('ntpath.abspath("?")', cwd_dir + "\\?")
Tim Grahamd03b7752018-10-25 11:26:38 -0400611 drive, _ = ntpath.splitdrive(cwd_dir)
612 tester('ntpath.abspath("/abc/")', drive + "\\abc")
Christian Heimesf6cd9672008-03-26 13:45:42 +0000613
614 def test_relpath(self):
Christian Heimesf6cd9672008-03-26 13:45:42 +0000615 tester('ntpath.relpath("a")', 'a')
Steve Dower75e06492019-08-21 13:43:06 -0700616 tester('ntpath.relpath(ntpath.abspath("a"))', 'a')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000617 tester('ntpath.relpath("a/b")', 'a\\b')
618 tester('ntpath.relpath("../a/b")', '..\\a\\b')
Hai Shi46605972020-08-04 00:49:18 +0800619 with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir:
Steve Dower75e06492019-08-21 13:43:06 -0700620 currentdir = ntpath.basename(cwd_dir)
Serhiy Storchaka5106d042015-01-26 10:26:14 +0200621 tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a')
622 tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000623 tester('ntpath.relpath("a", "b/c")', '..\\..\\a')
Mark Hammond5a607a32009-05-06 08:04:54 +0000624 tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000625 tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a')
626 tester('ntpath.relpath("a", "a")', '.')
Mark Hammond5a607a32009-05-06 08:04:54 +0000627 tester('ntpath.relpath("/foo/bar/bat", "/x/y/z")', '..\\..\\..\\foo\\bar\\bat')
628 tester('ntpath.relpath("/foo/bar/bat", "/foo/bar")', 'bat')
629 tester('ntpath.relpath("/foo/bar/bat", "/")', 'foo\\bar\\bat')
630 tester('ntpath.relpath("/", "/foo/bar/bat")', '..\\..\\..')
631 tester('ntpath.relpath("/foo/bar/bat", "/x")', '..\\foo\\bar\\bat')
632 tester('ntpath.relpath("/x", "/foo/bar/bat")', '..\\..\\..\\x')
633 tester('ntpath.relpath("/", "/")', '.')
634 tester('ntpath.relpath("/a", "/a")', '.')
635 tester('ntpath.relpath("/a/b", "/a/b")', '.')
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000636 tester('ntpath.relpath("c:/foo", "C:/FOO")', '.')
Christian Heimesf6cd9672008-03-26 13:45:42 +0000637
Serhiy Storchaka38220932015-03-31 15:31:53 +0300638 def test_commonpath(self):
639 def check(paths, expected):
640 tester(('ntpath.commonpath(%r)' % paths).replace('\\\\', '\\'),
641 expected)
642 def check_error(exc, paths):
643 self.assertRaises(exc, ntpath.commonpath, paths)
644 self.assertRaises(exc, ntpath.commonpath,
645 [os.fsencode(p) for p in paths])
646
647 self.assertRaises(ValueError, ntpath.commonpath, [])
648 check_error(ValueError, ['C:\\Program Files', 'Program Files'])
649 check_error(ValueError, ['C:\\Program Files', 'C:Program Files'])
650 check_error(ValueError, ['\\Program Files', 'Program Files'])
651 check_error(ValueError, ['Program Files', 'C:\\Program Files'])
652 check(['C:\\Program Files'], 'C:\\Program Files')
653 check(['C:\\Program Files', 'C:\\Program Files'], 'C:\\Program Files')
654 check(['C:\\Program Files\\', 'C:\\Program Files'],
655 'C:\\Program Files')
656 check(['C:\\Program Files\\', 'C:\\Program Files\\'],
657 'C:\\Program Files')
658 check(['C:\\\\Program Files', 'C:\\Program Files\\\\'],
659 'C:\\Program Files')
660 check(['C:\\.\\Program Files', 'C:\\Program Files\\.'],
661 'C:\\Program Files')
662 check(['C:\\', 'C:\\bin'], 'C:\\')
663 check(['C:\\Program Files', 'C:\\bin'], 'C:\\')
664 check(['C:\\Program Files', 'C:\\Program Files\\Bar'],
665 'C:\\Program Files')
666 check(['C:\\Program Files\\Foo', 'C:\\Program Files\\Bar'],
667 'C:\\Program Files')
668 check(['C:\\Program Files', 'C:\\Projects'], 'C:\\')
669 check(['C:\\Program Files\\', 'C:\\Projects'], 'C:\\')
670
671 check(['C:\\Program Files\\Foo', 'C:/Program Files/Bar'],
672 'C:\\Program Files')
673 check(['C:\\Program Files\\Foo', 'c:/program files/bar'],
674 'C:\\Program Files')
675 check(['c:/program files/bar', 'C:\\Program Files\\Foo'],
676 'c:\\program files')
677
678 check_error(ValueError, ['C:\\Program Files', 'D:\\Program Files'])
679
680 check(['spam'], 'spam')
681 check(['spam', 'spam'], 'spam')
682 check(['spam', 'alot'], '')
683 check(['and\\jam', 'and\\spam'], 'and')
684 check(['and\\\\jam', 'and\\spam\\\\'], 'and')
685 check(['and\\.\\jam', '.\\and\\spam'], 'and')
686 check(['and\\jam', 'and\\spam', 'alot'], '')
687 check(['and\\jam', 'and\\spam', 'and'], 'and')
688 check(['C:and\\jam', 'C:and\\spam'], 'C:and')
689
690 check([''], '')
691 check(['', 'spam\\alot'], '')
692 check_error(ValueError, ['', '\\spam\\alot'])
693
694 self.assertRaises(TypeError, ntpath.commonpath,
695 [b'C:\\Program Files', 'C:\\Program Files\\Foo'])
696 self.assertRaises(TypeError, ntpath.commonpath,
697 [b'C:\\Program Files', 'Program Files\\Foo'])
698 self.assertRaises(TypeError, ntpath.commonpath,
699 [b'Program Files', 'C:\\Program Files\\Foo'])
700 self.assertRaises(TypeError, ntpath.commonpath,
701 ['C:\\Program Files', b'C:\\Program Files\\Foo'])
702 self.assertRaises(TypeError, ntpath.commonpath,
703 ['C:\\Program Files', b'Program Files\\Foo'])
704 self.assertRaises(TypeError, ntpath.commonpath,
705 ['Program Files', b'C:\\Program Files\\Foo'])
706
Brian Curtin62857742010-09-06 17:07:27 +0000707 def test_sameopenfile(self):
708 with TemporaryFile() as tf1, TemporaryFile() as tf2:
709 # Make sure the same file is really the same
710 self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
711 # Make sure different files are really different
712 self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
Brian Curtin13a0db52010-09-06 19:46:17 +0000713 # Make sure invalid values don't cause issues on win32
714 if sys.platform == "win32":
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +0000715 with self.assertRaises(OSError):
Brian Curtin13a0db52010-09-06 19:46:17 +0000716 # Invalid file descriptors shouldn't display assert
717 # dialogs (#4804)
718 ntpath.sameopenfile(-1, -1)
Brian Curtin62857742010-09-06 17:07:27 +0000719
Tim Golden6b528062013-08-01 12:44:00 +0100720 def test_ismount(self):
721 self.assertTrue(ntpath.ismount("c:\\"))
722 self.assertTrue(ntpath.ismount("C:\\"))
723 self.assertTrue(ntpath.ismount("c:/"))
724 self.assertTrue(ntpath.ismount("C:/"))
725 self.assertTrue(ntpath.ismount("\\\\.\\c:\\"))
726 self.assertTrue(ntpath.ismount("\\\\.\\C:\\"))
727
728 self.assertTrue(ntpath.ismount(b"c:\\"))
729 self.assertTrue(ntpath.ismount(b"C:\\"))
730 self.assertTrue(ntpath.ismount(b"c:/"))
731 self.assertTrue(ntpath.ismount(b"C:/"))
732 self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\"))
733 self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\"))
734
Hai Shi46605972020-08-04 00:49:18 +0800735 with os_helper.temp_dir() as d:
Tim Golden6b528062013-08-01 12:44:00 +0100736 self.assertFalse(ntpath.ismount(d))
737
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100738 if sys.platform == "win32":
739 #
740 # Make sure the current folder isn't the root folder
741 # (or any other volume root). The drive-relative
742 # locations below cannot then refer to mount points
743 #
744 drive, path = ntpath.splitdrive(sys.executable)
Hai Shi598a9512020-08-07 23:18:38 +0800745 with os_helper.change_cwd(ntpath.dirname(sys.executable)):
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100746 self.assertFalse(ntpath.ismount(drive.lower()))
747 self.assertFalse(ntpath.ismount(drive.upper()))
Tim Golden6b528062013-08-01 12:44:00 +0100748
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100749 self.assertTrue(ntpath.ismount("\\\\localhost\\c$"))
750 self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\"))
Tim Golden6b528062013-08-01 12:44:00 +0100751
Tim Goldenb2fcebb2013-08-01 13:58:58 +0100752 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$"))
753 self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\"))
Christian Heimesf6cd9672008-03-26 13:45:42 +0000754
Tim Goldenff64add2018-07-25 14:36:54 +0100755 def assertEqualCI(self, s1, s2):
756 """Assert that two strings are equal ignoring case differences."""
757 self.assertEqual(s1.lower(), s2.lower())
758
Steve Dower23ad6d02018-02-22 10:39:10 -0800759 @unittest.skipUnless(nt, "OS helpers require 'nt' module")
760 def test_nt_helpers(self):
761 # Trivial validation that the helpers do not break, and support both
762 # unicode and bytes (UTF-8) paths
763
Tim Goldenff64add2018-07-25 14:36:54 +0100764 executable = nt._getfinalpathname(sys.executable)
765
766 for path in executable, os.fsencode(executable):
767 volume_path = nt._getvolumepathname(path)
768 path_drive = ntpath.splitdrive(path)[0]
769 volume_path_drive = ntpath.splitdrive(volume_path)[0]
770 self.assertEqualCI(path_drive, volume_path_drive)
Steve Dower23ad6d02018-02-22 10:39:10 -0800771
772 cap, free = nt._getdiskusage(sys.exec_prefix)
773 self.assertGreater(cap, 0)
774 self.assertGreater(free, 0)
775 b_cap, b_free = nt._getdiskusage(sys.exec_prefix.encode())
776 # Free space may change, so only test the capacity is equal
777 self.assertEqual(b_cap, cap)
778 self.assertGreater(b_free, 0)
779
780 for path in [sys.prefix, sys.executable]:
781 final_path = nt._getfinalpathname(path)
782 self.assertIsInstance(final_path, str)
783 self.assertGreater(len(final_path), 0)
784
785 b_final_path = nt._getfinalpathname(path.encode())
786 self.assertIsInstance(b_final_path, bytes)
787 self.assertGreater(len(b_final_path), 0)
788
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200789class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000790 pathmodule = ntpath
Serhiy Storchaka9ed707e2017-01-13 20:55:05 +0200791 attributes = ['relpath']
Florent Xiclunac9c79782010-03-08 12:24:53 +0000792
793
Steve Dower97d79062019-09-10 14:52:48 +0100794class PathLikeTests(NtpathTestCase):
Brett Cannon3f9183b2016-08-26 14:44:48 -0700795
796 path = ntpath
797
Brett Cannon3f9183b2016-08-26 14:44:48 -0700798 def setUp(self):
Hai Shi46605972020-08-04 00:49:18 +0800799 self.file_name = os_helper.TESTFN
800 self.file_path = FakePath(os_helper.TESTFN)
801 self.addCleanup(os_helper.unlink, self.file_name)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700802 with open(self.file_name, 'xb', 0) as file:
803 file.write(b"test_ntpath.PathLikeTests")
804
Steve Dower97d79062019-09-10 14:52:48 +0100805 def _check_function(self, func):
806 self.assertPathEqual(func(self.file_path), func(self.file_name))
Brett Cannon3f9183b2016-08-26 14:44:48 -0700807
808 def test_path_normcase(self):
Steve Dower97d79062019-09-10 14:52:48 +0100809 self._check_function(self.path.normcase)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700810
811 def test_path_isabs(self):
Steve Dower97d79062019-09-10 14:52:48 +0100812 self._check_function(self.path.isabs)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700813
814 def test_path_join(self):
Serhiy Storchakab21d1552018-03-02 11:53:51 +0200815 self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
Brett Cannon3f9183b2016-08-26 14:44:48 -0700816 self.path.join('a', 'b', 'c'))
817
818 def test_path_split(self):
Steve Dower97d79062019-09-10 14:52:48 +0100819 self._check_function(self.path.split)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700820
821 def test_path_splitext(self):
Steve Dower97d79062019-09-10 14:52:48 +0100822 self._check_function(self.path.splitext)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700823
824 def test_path_splitdrive(self):
Steve Dower97d79062019-09-10 14:52:48 +0100825 self._check_function(self.path.splitdrive)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700826
827 def test_path_basename(self):
Steve Dower97d79062019-09-10 14:52:48 +0100828 self._check_function(self.path.basename)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700829
830 def test_path_dirname(self):
Steve Dower97d79062019-09-10 14:52:48 +0100831 self._check_function(self.path.dirname)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700832
833 def test_path_islink(self):
Steve Dower97d79062019-09-10 14:52:48 +0100834 self._check_function(self.path.islink)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700835
836 def test_path_lexists(self):
Steve Dower97d79062019-09-10 14:52:48 +0100837 self._check_function(self.path.lexists)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700838
839 def test_path_ismount(self):
Steve Dower97d79062019-09-10 14:52:48 +0100840 self._check_function(self.path.ismount)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700841
842 def test_path_expanduser(self):
Steve Dower97d79062019-09-10 14:52:48 +0100843 self._check_function(self.path.expanduser)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700844
845 def test_path_expandvars(self):
Steve Dower97d79062019-09-10 14:52:48 +0100846 self._check_function(self.path.expandvars)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700847
848 def test_path_normpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100849 self._check_function(self.path.normpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700850
851 def test_path_abspath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100852 self._check_function(self.path.abspath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700853
854 def test_path_realpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100855 self._check_function(self.path.realpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700856
857 def test_path_relpath(self):
Steve Dower97d79062019-09-10 14:52:48 +0100858 self._check_function(self.path.relpath)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700859
860 def test_path_commonpath(self):
861 common_path = self.path.commonpath([self.file_path, self.file_name])
Steve Dower97d79062019-09-10 14:52:48 +0100862 self.assertPathEqual(common_path, self.file_name)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700863
864 def test_path_isdir(self):
Steve Dower97d79062019-09-10 14:52:48 +0100865 self._check_function(self.path.isdir)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700866
867
Christian Heimesf6cd9672008-03-26 13:45:42 +0000868if __name__ == "__main__":
869 unittest.main()