blob: 4ff445d400ea1b100ab64251e0f3e2509442abb9 [file] [log] [blame]
Brian Curtind40e6f72010-07-08 21:39:08 +00001import os
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002import posixpath
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003import unittest
4import warnings
Georg Brandl89fad142010-03-14 10:23:39 +00005from posixpath import realpath, abspath, dirname, basename
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006from test import support, test_genericpath
Johannes Gijsbers4ec40642004-08-14 15:01:53 +00007
Michael Foord07926f02011-03-16 17:19:16 -04008try:
9 import posix
10except ImportError:
11 posix = None
12
Johannes Gijsbers4ec40642004-08-14 15:01:53 +000013# An absolute path to a temporary filename for testing. We can't rely on TESTFN
14# being an absolute path, so we need this.
15
Benjamin Petersonee8712c2008-05-20 21:35:26 +000016ABSTFN = abspath(support.TESTFN)
Skip Montanaroe809b002000-07-12 00:20:08 +000017
Brian Curtind40e6f72010-07-08 21:39:08 +000018def skip_if_ABSTFN_contains_backslash(test):
19 """
20 On Windows, posixpath.abspath still returns paths with backslashes
21 instead of posix forward slashes. If this is the case, several tests
22 fail, so skip them.
23 """
24 found_backslash = '\\' in ABSTFN
25 msg = "ABSTFN is not a posix path - tests fail"
26 return [test, unittest.skip(msg)(test)][found_backslash]
27
Guido van Rossumd8faa362007-04-27 19:54:29 +000028def safe_rmdir(dirname):
29 try:
30 os.rmdir(dirname)
31 except OSError:
32 pass
33
Brett Cannonb47243a2003-06-16 21:54:50 +000034class PosixPathTest(unittest.TestCase):
Skip Montanaroe809b002000-07-12 00:20:08 +000035
Guido van Rossumd8faa362007-04-27 19:54:29 +000036 def setUp(self):
37 self.tearDown()
38
39 def tearDown(self):
40 for suffix in ["", "1", "2"]:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000041 support.unlink(support.TESTFN + suffix)
42 safe_rmdir(support.TESTFN + suffix)
Guido van Rossumd8faa362007-04-27 19:54:29 +000043
Brett Cannonb47243a2003-06-16 21:54:50 +000044 def test_join(self):
Guido van Rossumf0af3e32008-10-02 18:55:37 +000045 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"),
46 "/bar/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +000047 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
Guido van Rossumf0af3e32008-10-02 18:55:37 +000048 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"),
49 "/foo/bar/baz/")
50
51 self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"),
52 b"/bar/baz")
53 self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"),
54 b"/foo/bar/baz")
55 self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"),
56 b"/foo/bar/baz/")
Skip Montanaroe809b002000-07-12 00:20:08 +000057
Brett Cannonb47243a2003-06-16 21:54:50 +000058 def test_split(self):
59 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
60 self.assertEqual(posixpath.split("/"), ("/", ""))
61 self.assertEqual(posixpath.split("foo"), ("", "foo"))
62 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
63 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
64
Guido van Rossumf0af3e32008-10-02 18:55:37 +000065 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
66 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
67 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
68 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
69 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
70
Guido van Rossumd8faa362007-04-27 19:54:29 +000071 def splitextTest(self, path, filename, ext):
72 self.assertEqual(posixpath.splitext(path), (filename, ext))
73 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000074 self.assertEqual(posixpath.splitext("abc/" + path),
75 ("abc/" + filename, ext))
76 self.assertEqual(posixpath.splitext("abc.def/" + path),
77 ("abc.def/" + filename, ext))
78 self.assertEqual(posixpath.splitext("/abc.def/" + path),
79 ("/abc.def/" + filename, ext))
80 self.assertEqual(posixpath.splitext(path + "/"),
81 (filename + ext + "/", ""))
82
83 path = bytes(path, "ASCII")
84 filename = bytes(filename, "ASCII")
85 ext = bytes(ext, "ASCII")
86
87 self.assertEqual(posixpath.splitext(path), (filename, ext))
88 self.assertEqual(posixpath.splitext(b"/" + path),
89 (b"/" + filename, ext))
90 self.assertEqual(posixpath.splitext(b"abc/" + path),
91 (b"abc/" + filename, ext))
92 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
93 (b"abc.def/" + filename, ext))
94 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
95 (b"/abc.def/" + filename, ext))
96 self.assertEqual(posixpath.splitext(path + b"/"),
97 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +000098
Guido van Rossumd8faa362007-04-27 19:54:29 +000099 def test_splitext(self):
100 self.splitextTest("foo.bar", "foo", ".bar")
101 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
102 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
103 self.splitextTest(".csh.rc", ".csh", ".rc")
104 self.splitextTest("nodots", "nodots", "")
105 self.splitextTest(".cshrc", ".cshrc", "")
106 self.splitextTest("...manydots", "...manydots", "")
107 self.splitextTest("...manydots.ext", "...manydots", ".ext")
108 self.splitextTest(".", ".", "")
109 self.splitextTest("..", "..", "")
110 self.splitextTest("........", "........", "")
111 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000112
113 def test_isabs(self):
114 self.assertIs(posixpath.isabs(""), False)
115 self.assertIs(posixpath.isabs("/"), True)
116 self.assertIs(posixpath.isabs("/foo"), True)
117 self.assertIs(posixpath.isabs("/foo/bar"), True)
118 self.assertIs(posixpath.isabs("foo/bar"), False)
119
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000120 self.assertIs(posixpath.isabs(b""), False)
121 self.assertIs(posixpath.isabs(b"/"), True)
122 self.assertIs(posixpath.isabs(b"/foo"), True)
123 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
124 self.assertIs(posixpath.isabs(b"foo/bar"), False)
125
Brett Cannonb47243a2003-06-16 21:54:50 +0000126 def test_basename(self):
127 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
128 self.assertEqual(posixpath.basename("/"), "")
129 self.assertEqual(posixpath.basename("foo"), "foo")
130 self.assertEqual(posixpath.basename("////foo"), "foo")
131 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
132
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000133 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
134 self.assertEqual(posixpath.basename(b"/"), b"")
135 self.assertEqual(posixpath.basename(b"foo"), b"foo")
136 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
137 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
138
Brett Cannonb47243a2003-06-16 21:54:50 +0000139 def test_dirname(self):
140 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
141 self.assertEqual(posixpath.dirname("/"), "/")
142 self.assertEqual(posixpath.dirname("foo"), "")
143 self.assertEqual(posixpath.dirname("////foo"), "////")
144 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
145
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000146 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
147 self.assertEqual(posixpath.dirname(b"/"), b"/")
148 self.assertEqual(posixpath.dirname(b"foo"), b"")
149 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
150 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
151
Brett Cannonb47243a2003-06-16 21:54:50 +0000152 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000153 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400154 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000155 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000156 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000157 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000158 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000159 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000160 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000161 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
162 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
163 os.remove(support.TESTFN + "1")
164 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
165 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
166 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000167 finally:
168 if not f.close():
169 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000170
Brett Cannonb47243a2003-06-16 21:54:50 +0000171 def test_ismount(self):
172 self.assertIs(posixpath.ismount("/"), True)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100173 with warnings.catch_warnings():
174 warnings.simplefilter("ignore", DeprecationWarning)
175 self.assertIs(posixpath.ismount(b"/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400176
177 def test_ismount_non_existent(self):
178 # Non-existent mountpoint.
179 self.assertIs(posixpath.ismount(ABSTFN), False)
180 try:
181 os.mkdir(ABSTFN)
182 self.assertIs(posixpath.ismount(ABSTFN), False)
183 finally:
184 safe_rmdir(ABSTFN)
185
186 @unittest.skipUnless(support.can_symlink(),
187 "Test requires symlink support")
188 def test_ismount_symlinks(self):
189 # Symlinks are never mountpoints.
190 try:
191 os.symlink("/", ABSTFN)
192 self.assertIs(posixpath.ismount(ABSTFN), False)
193 finally:
194 os.unlink(ABSTFN)
195
196 @unittest.skipIf(posix is None, "Test requires posix module")
197 def test_ismount_different_device(self):
198 # Simulate the path being on a different device from its parent by
199 # mocking out st_dev.
200 save_lstat = os.lstat
201 def fake_lstat(path):
202 st_ino = 0
203 st_dev = 0
204 if path == ABSTFN:
205 st_dev = 1
206 st_ino = 1
207 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
208 try:
209 os.lstat = fake_lstat
210 self.assertIs(posixpath.ismount(ABSTFN), True)
211 finally:
212 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000213
Brett Cannonb47243a2003-06-16 21:54:50 +0000214 def test_expanduser(self):
215 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000216 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Serhiy Storchakaa3fd0b22016-05-03 21:17:03 +0300217 with support.EnvironmentVarGuard() as env:
218 for home in '/', '', '//', '///':
219 with self.subTest(home=home):
220 env['HOME'] = home
221 self.assertEqual(posixpath.expanduser("~"), "/")
222 self.assertEqual(posixpath.expanduser("~/"), "/")
223 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000224 try:
225 import pwd
226 except ImportError:
227 pass
228 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000229 self.assertIsInstance(posixpath.expanduser("~/"), str)
230 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000231 # if home directory == root directory, this test makes no sense
232 if posixpath.expanduser("~") != '/':
233 self.assertEqual(
234 posixpath.expanduser("~") + "/",
235 posixpath.expanduser("~/")
236 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000237 self.assertEqual(
238 posixpath.expanduser(b"~") + b"/",
239 posixpath.expanduser(b"~/")
240 )
Ezio Melottie9615932010-01-24 19:26:24 +0000241 self.assertIsInstance(posixpath.expanduser("~root/"), str)
242 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
243 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
244 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000245
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000246 with support.EnvironmentVarGuard() as env:
Michael Foord07926f02011-03-16 17:19:16 -0400247 # expanduser should fall back to using the password database
248 del env['HOME']
249 home = pwd.getpwuid(os.getuid()).pw_dir
Ezio Melottice82d572013-05-09 15:19:45 +0300250 # $HOME can end with a trailing /, so strip it (see #17809)
Serhiy Storchakaa3fd0b22016-05-03 21:17:03 +0300251 home = home.rstrip("/") or '/'
252 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000253
Brett Cannonb47243a2003-06-16 21:54:50 +0000254 def test_normpath(self):
255 self.assertEqual(posixpath.normpath(""), ".")
256 self.assertEqual(posixpath.normpath("/"), "/")
257 self.assertEqual(posixpath.normpath("//"), "//")
258 self.assertEqual(posixpath.normpath("///"), "/")
259 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000260 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
261 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000262 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
263
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000264 self.assertEqual(posixpath.normpath(b""), b".")
265 self.assertEqual(posixpath.normpath(b"/"), b"/")
266 self.assertEqual(posixpath.normpath(b"//"), b"//")
267 self.assertEqual(posixpath.normpath(b"///"), b"/")
268 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
269 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
270 b"/foo/baz")
271 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
272 b"/foo/bar")
273
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200274 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200275 def test_realpath_curdir(self):
276 self.assertEqual(realpath('.'), os.getcwd())
277 self.assertEqual(realpath('./.'), os.getcwd())
278 self.assertEqual(realpath('/'.join(['.'] * 100)), os.getcwd())
279
280 self.assertEqual(realpath(b'.'), os.getcwdb())
281 self.assertEqual(realpath(b'./.'), os.getcwdb())
282 self.assertEqual(realpath(b'/'.join([b'.'] * 100)), os.getcwdb())
283
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200284 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200285 def test_realpath_pardir(self):
286 self.assertEqual(realpath('..'), dirname(os.getcwd()))
287 self.assertEqual(realpath('../..'), dirname(dirname(os.getcwd())))
288 self.assertEqual(realpath('/'.join(['..'] * 100)), '/')
289
290 self.assertEqual(realpath(b'..'), dirname(os.getcwdb()))
291 self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb())))
292 self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/')
293
Brian Curtin52173d42010-12-02 18:29:18 +0000294 @unittest.skipUnless(hasattr(os, "symlink"),
295 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000296 @skip_if_ABSTFN_contains_backslash
297 def test_realpath_basic(self):
298 # Basic operation.
299 try:
300 os.symlink(ABSTFN+"1", ABSTFN)
301 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
302 finally:
303 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000304
Brian Curtin52173d42010-12-02 18:29:18 +0000305 @unittest.skipUnless(hasattr(os, "symlink"),
306 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000307 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400308 def test_realpath_relative(self):
309 try:
310 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
311 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
312 finally:
313 support.unlink(ABSTFN)
314
315 @unittest.skipUnless(hasattr(os, "symlink"),
316 "Missing symlink implementation")
317 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000318 def test_realpath_symlink_loops(self):
319 # Bug #930024, return the path unchanged if we get into an infinite
320 # symlink loop.
321 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000322 os.symlink(ABSTFN, ABSTFN)
323 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000324
Brian Curtind40e6f72010-07-08 21:39:08 +0000325 os.symlink(ABSTFN+"1", ABSTFN+"2")
326 os.symlink(ABSTFN+"2", ABSTFN+"1")
327 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
328 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000329
Serhiy Storchakadf326912013-02-10 12:22:07 +0200330 self.assertEqual(realpath(ABSTFN+"1/x"), ABSTFN+"1/x")
331 self.assertEqual(realpath(ABSTFN+"1/.."), dirname(ABSTFN))
332 self.assertEqual(realpath(ABSTFN+"1/../x"), dirname(ABSTFN) + "/x")
333 os.symlink(ABSTFN+"x", ABSTFN+"y")
334 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "y"),
335 ABSTFN + "y")
336 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "1"),
337 ABSTFN + "1")
338
339 os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
340 self.assertEqual(realpath(ABSTFN+"a"), ABSTFN+"a/b")
341
342 os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
343 basename(ABSTFN) + "c", ABSTFN+"c")
344 self.assertEqual(realpath(ABSTFN+"c"), ABSTFN+"c")
345
Brian Curtind40e6f72010-07-08 21:39:08 +0000346 # Test using relative path as well.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300347 with support.change_cwd(dirname(ABSTFN)):
348 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
Brian Curtind40e6f72010-07-08 21:39:08 +0000349 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000350 support.unlink(ABSTFN)
351 support.unlink(ABSTFN+"1")
352 support.unlink(ABSTFN+"2")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200353 support.unlink(ABSTFN+"y")
354 support.unlink(ABSTFN+"c")
Ezio Melotti136726c2013-03-01 20:59:17 +0200355 support.unlink(ABSTFN+"a")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200356
357 @unittest.skipUnless(hasattr(os, "symlink"),
358 "Missing symlink implementation")
359 @skip_if_ABSTFN_contains_backslash
360 def test_realpath_repeated_indirect_symlinks(self):
361 # Issue #6975.
362 try:
363 os.mkdir(ABSTFN)
364 os.symlink('../' + basename(ABSTFN), ABSTFN + '/self')
365 os.symlink('self/self/self', ABSTFN + '/link')
366 self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN)
367 finally:
368 support.unlink(ABSTFN + '/self')
369 support.unlink(ABSTFN + '/link')
370 safe_rmdir(ABSTFN)
371
372 @unittest.skipUnless(hasattr(os, "symlink"),
373 "Missing symlink implementation")
374 @skip_if_ABSTFN_contains_backslash
375 def test_realpath_deep_recursion(self):
376 depth = 10
Serhiy Storchakadf326912013-02-10 12:22:07 +0200377 try:
378 os.mkdir(ABSTFN)
379 for i in range(depth):
380 os.symlink('/'.join(['%d' % i] * 10), ABSTFN + '/%d' % (i + 1))
381 os.symlink('.', ABSTFN + '/0')
382 self.assertEqual(realpath(ABSTFN + '/%d' % depth), ABSTFN)
383
384 # Test using relative path as well.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300385 with support.change_cwd(ABSTFN):
386 self.assertEqual(realpath('%d' % depth), ABSTFN)
Serhiy Storchakadf326912013-02-10 12:22:07 +0200387 finally:
Serhiy Storchakadf326912013-02-10 12:22:07 +0200388 for i in range(depth + 1):
389 support.unlink(ABSTFN + '/%d' % i)
390 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000391
Brian Curtin52173d42010-12-02 18:29:18 +0000392 @unittest.skipUnless(hasattr(os, "symlink"),
393 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000394 @skip_if_ABSTFN_contains_backslash
395 def test_realpath_resolve_parents(self):
396 # We also need to resolve any symlinks in the parents of a relative
397 # path passed to realpath. E.g.: current working directory is
398 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
399 # realpath("a"). This should return /usr/share/doc/a/.
400 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000401 os.mkdir(ABSTFN)
402 os.mkdir(ABSTFN + "/y")
403 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000404
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300405 with support.change_cwd(ABSTFN + "/k"):
406 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
Brian Curtind40e6f72010-07-08 21:39:08 +0000407 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000408 support.unlink(ABSTFN + "/k")
409 safe_rmdir(ABSTFN + "/y")
410 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000411
Brian Curtin52173d42010-12-02 18:29:18 +0000412 @unittest.skipUnless(hasattr(os, "symlink"),
413 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000414 @skip_if_ABSTFN_contains_backslash
415 def test_realpath_resolve_before_normalizing(self):
416 # Bug #990669: Symbolic links should be resolved before we
417 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
418 # in the following hierarchy:
419 # a/k/y
420 #
421 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
422 # then realpath("link-y/..") should return 'k', not 'a'.
423 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000424 os.mkdir(ABSTFN)
425 os.mkdir(ABSTFN + "/k")
426 os.mkdir(ABSTFN + "/k/y")
427 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000428
Brian Curtind40e6f72010-07-08 21:39:08 +0000429 # Absolute path.
430 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
431 # Relative path.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300432 with support.change_cwd(dirname(ABSTFN)):
433 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
434 ABSTFN + "/k")
Brian Curtind40e6f72010-07-08 21:39:08 +0000435 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000436 support.unlink(ABSTFN + "/link-y")
437 safe_rmdir(ABSTFN + "/k/y")
438 safe_rmdir(ABSTFN + "/k")
439 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000440
Brian Curtin52173d42010-12-02 18:29:18 +0000441 @unittest.skipUnless(hasattr(os, "symlink"),
442 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000443 @skip_if_ABSTFN_contains_backslash
444 def test_realpath_resolve_first(self):
445 # Bug #1213894: The first component of the path, if not absolute,
446 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000447
Brian Curtind40e6f72010-07-08 21:39:08 +0000448 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000449 os.mkdir(ABSTFN)
450 os.mkdir(ABSTFN + "/k")
451 os.symlink(ABSTFN, ABSTFN + "link")
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300452 with support.change_cwd(dirname(ABSTFN)):
453 base = basename(ABSTFN)
454 self.assertEqual(realpath(base + "link"), ABSTFN)
455 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
Brian Curtind40e6f72010-07-08 21:39:08 +0000456 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000457 support.unlink(ABSTFN + "link")
458 safe_rmdir(ABSTFN + "/k")
459 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000460
Guido van Rossumd8faa362007-04-27 19:54:29 +0000461 def test_relpath(self):
462 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
463 try:
464 curdir = os.path.split(os.getcwd())[-1]
465 self.assertRaises(ValueError, posixpath.relpath, "")
466 self.assertEqual(posixpath.relpath("a"), "a")
467 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
468 self.assertEqual(posixpath.relpath("a/b"), "a/b")
469 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
470 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000471 self.assertEqual(posixpath.relpath("a/b", "../c"),
472 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000473 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000474 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000475 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
476 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
477 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
478 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
479 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
480 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
481 self.assertEqual(posixpath.relpath("/", "/"), '.')
482 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
483 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000484 finally:
485 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000486
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000487 def test_relpath_bytes(self):
488 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
489 try:
490 curdir = os.path.split(os.getcwdb())[-1]
491 self.assertRaises(ValueError, posixpath.relpath, b"")
492 self.assertEqual(posixpath.relpath(b"a"), b"a")
493 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
494 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
495 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
496 self.assertEqual(posixpath.relpath(b"a", b"../b"),
497 b"../"+curdir+b"/a")
498 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
499 b"../"+curdir+b"/a/b")
500 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
501 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000502 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
503 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
504 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
505 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
506 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
507 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
508 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
509 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
510 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000511
512 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
513 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
514 finally:
515 os.getcwdb = real_getcwdb
516
Serhiy Storchaka38220932015-03-31 15:31:53 +0300517 def test_commonpath(self):
518 def check(paths, expected):
519 self.assertEqual(posixpath.commonpath(paths), expected)
520 self.assertEqual(posixpath.commonpath([os.fsencode(p) for p in paths]),
521 os.fsencode(expected))
522 def check_error(exc, paths):
523 self.assertRaises(exc, posixpath.commonpath, paths)
524 self.assertRaises(exc, posixpath.commonpath,
525 [os.fsencode(p) for p in paths])
526
527 self.assertRaises(ValueError, posixpath.commonpath, [])
528 check_error(ValueError, ['/usr', 'usr'])
529 check_error(ValueError, ['usr', '/usr'])
530
531 check(['/usr/local'], '/usr/local')
532 check(['/usr/local', '/usr/local'], '/usr/local')
533 check(['/usr/local/', '/usr/local'], '/usr/local')
534 check(['/usr/local/', '/usr/local/'], '/usr/local')
535 check(['/usr//local', '//usr/local'], '/usr/local')
536 check(['/usr/./local', '/./usr/local'], '/usr/local')
537 check(['/', '/dev'], '/')
538 check(['/usr', '/dev'], '/')
539 check(['/usr/lib/', '/usr/lib/python3'], '/usr/lib')
540 check(['/usr/lib/', '/usr/lib64/'], '/usr')
541
542 check(['/usr/lib', '/usr/lib64'], '/usr')
543 check(['/usr/lib/', '/usr/lib64'], '/usr')
544
545 check(['spam'], 'spam')
546 check(['spam', 'spam'], 'spam')
547 check(['spam', 'alot'], '')
548 check(['and/jam', 'and/spam'], 'and')
549 check(['and//jam', 'and/spam//'], 'and')
550 check(['and/./jam', './and/spam'], 'and')
551 check(['and/jam', 'and/spam', 'alot'], '')
552 check(['and/jam', 'and/spam', 'and'], 'and')
553
554 check([''], '')
555 check(['', 'spam/alot'], '')
556 check_error(ValueError, ['', '/spam/alot'])
557
558 self.assertRaises(TypeError, posixpath.commonpath,
559 [b'/usr/lib/', '/usr/lib/python3'])
560 self.assertRaises(TypeError, posixpath.commonpath,
561 [b'/usr/lib/', 'usr/lib/python3'])
562 self.assertRaises(TypeError, posixpath.commonpath,
563 [b'usr/lib/', '/usr/lib/python3'])
564 self.assertRaises(TypeError, posixpath.commonpath,
565 ['/usr/lib/', b'/usr/lib/python3'])
566 self.assertRaises(TypeError, posixpath.commonpath,
567 ['/usr/lib/', b'usr/lib/python3'])
568 self.assertRaises(TypeError, posixpath.commonpath,
569 ['usr/lib/', b'/usr/lib/python3'])
570
Florent Xiclunac9c79782010-03-08 12:24:53 +0000571
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200572class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000573 pathmodule = posixpath
574 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
575
576
Brett Cannonb47243a2003-06-16 21:54:50 +0000577if __name__=="__main__":
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200578 unittest.main()