blob: 8b3ce70c84969f11525be46355befa474eeb3a47 [file] [log] [blame]
Hynek Schlawackc5a45662012-07-17 13:05:43 +02001import itertools
Brian Curtind40e6f72010-07-08 21:39:08 +00002import os
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003import posixpath
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004import unittest
5import warnings
Georg Brandl89fad142010-03-14 10:23:39 +00006from posixpath import realpath, abspath, dirname, basename
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01007from test import support, test_genericpath
Johannes Gijsbers4ec40642004-08-14 15:01:53 +00008
Michael Foord07926f02011-03-16 17:19:16 -04009try:
10 import posix
11except ImportError:
12 posix = None
13
Johannes Gijsbers4ec40642004-08-14 15:01:53 +000014# An absolute path to a temporary filename for testing. We can't rely on TESTFN
15# being an absolute path, so we need this.
16
Benjamin Petersonee8712c2008-05-20 21:35:26 +000017ABSTFN = abspath(support.TESTFN)
Skip Montanaroe809b002000-07-12 00:20:08 +000018
Brian Curtind40e6f72010-07-08 21:39:08 +000019def skip_if_ABSTFN_contains_backslash(test):
20 """
21 On Windows, posixpath.abspath still returns paths with backslashes
22 instead of posix forward slashes. If this is the case, several tests
23 fail, so skip them.
24 """
25 found_backslash = '\\' in ABSTFN
26 msg = "ABSTFN is not a posix path - tests fail"
27 return [test, unittest.skip(msg)(test)][found_backslash]
28
Guido van Rossumd8faa362007-04-27 19:54:29 +000029def safe_rmdir(dirname):
30 try:
31 os.rmdir(dirname)
32 except OSError:
33 pass
34
Brett Cannonb47243a2003-06-16 21:54:50 +000035class PosixPathTest(unittest.TestCase):
Skip Montanaroe809b002000-07-12 00:20:08 +000036
Guido van Rossumd8faa362007-04-27 19:54:29 +000037 def setUp(self):
38 self.tearDown()
39
40 def tearDown(self):
41 for suffix in ["", "1", "2"]:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000042 support.unlink(support.TESTFN + suffix)
43 safe_rmdir(support.TESTFN + suffix)
Guido van Rossumd8faa362007-04-27 19:54:29 +000044
Brett Cannonb47243a2003-06-16 21:54:50 +000045 def test_join(self):
Guido van Rossumf0af3e32008-10-02 18:55:37 +000046 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"),
47 "/bar/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +000048 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
Guido van Rossumf0af3e32008-10-02 18:55:37 +000049 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"),
50 "/foo/bar/baz/")
51
52 self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"),
53 b"/bar/baz")
54 self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"),
55 b"/foo/bar/baz")
56 self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"),
57 b"/foo/bar/baz/")
Skip Montanaroe809b002000-07-12 00:20:08 +000058
Brett Cannonb47243a2003-06-16 21:54:50 +000059 def test_split(self):
60 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
61 self.assertEqual(posixpath.split("/"), ("/", ""))
62 self.assertEqual(posixpath.split("foo"), ("", "foo"))
63 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
64 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
65
Guido van Rossumf0af3e32008-10-02 18:55:37 +000066 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
67 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
68 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
69 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
70 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
71
Guido van Rossumd8faa362007-04-27 19:54:29 +000072 def splitextTest(self, path, filename, ext):
73 self.assertEqual(posixpath.splitext(path), (filename, ext))
74 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000075 self.assertEqual(posixpath.splitext("abc/" + path),
76 ("abc/" + filename, ext))
77 self.assertEqual(posixpath.splitext("abc.def/" + path),
78 ("abc.def/" + filename, ext))
79 self.assertEqual(posixpath.splitext("/abc.def/" + path),
80 ("/abc.def/" + filename, ext))
81 self.assertEqual(posixpath.splitext(path + "/"),
82 (filename + ext + "/", ""))
83
84 path = bytes(path, "ASCII")
85 filename = bytes(filename, "ASCII")
86 ext = bytes(ext, "ASCII")
87
88 self.assertEqual(posixpath.splitext(path), (filename, ext))
89 self.assertEqual(posixpath.splitext(b"/" + path),
90 (b"/" + filename, ext))
91 self.assertEqual(posixpath.splitext(b"abc/" + path),
92 (b"abc/" + filename, ext))
93 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
94 (b"abc.def/" + filename, ext))
95 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
96 (b"/abc.def/" + filename, ext))
97 self.assertEqual(posixpath.splitext(path + b"/"),
98 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +000099
Guido van Rossumd8faa362007-04-27 19:54:29 +0000100 def test_splitext(self):
101 self.splitextTest("foo.bar", "foo", ".bar")
102 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
103 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
104 self.splitextTest(".csh.rc", ".csh", ".rc")
105 self.splitextTest("nodots", "nodots", "")
106 self.splitextTest(".cshrc", ".cshrc", "")
107 self.splitextTest("...manydots", "...manydots", "")
108 self.splitextTest("...manydots.ext", "...manydots", ".ext")
109 self.splitextTest(".", ".", "")
110 self.splitextTest("..", "..", "")
111 self.splitextTest("........", "........", "")
112 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000113
114 def test_isabs(self):
115 self.assertIs(posixpath.isabs(""), False)
116 self.assertIs(posixpath.isabs("/"), True)
117 self.assertIs(posixpath.isabs("/foo"), True)
118 self.assertIs(posixpath.isabs("/foo/bar"), True)
119 self.assertIs(posixpath.isabs("foo/bar"), False)
120
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000121 self.assertIs(posixpath.isabs(b""), False)
122 self.assertIs(posixpath.isabs(b"/"), True)
123 self.assertIs(posixpath.isabs(b"/foo"), True)
124 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
125 self.assertIs(posixpath.isabs(b"foo/bar"), False)
126
Brett Cannonb47243a2003-06-16 21:54:50 +0000127 def test_basename(self):
128 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
129 self.assertEqual(posixpath.basename("/"), "")
130 self.assertEqual(posixpath.basename("foo"), "foo")
131 self.assertEqual(posixpath.basename("////foo"), "foo")
132 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
133
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000134 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
135 self.assertEqual(posixpath.basename(b"/"), b"")
136 self.assertEqual(posixpath.basename(b"foo"), b"foo")
137 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
138 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
139
Brett Cannonb47243a2003-06-16 21:54:50 +0000140 def test_dirname(self):
141 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
142 self.assertEqual(posixpath.dirname("/"), "/")
143 self.assertEqual(posixpath.dirname("foo"), "")
144 self.assertEqual(posixpath.dirname("////foo"), "////")
145 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
146
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000147 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
148 self.assertEqual(posixpath.dirname(b"/"), b"/")
149 self.assertEqual(posixpath.dirname(b"foo"), b"")
150 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
151 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
152
Brett Cannonb47243a2003-06-16 21:54:50 +0000153 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000154 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400155 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000156 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000157 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000158 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000159 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000160 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000161 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000162 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
163 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
164 os.remove(support.TESTFN + "1")
165 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
166 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
167 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000168 finally:
169 if not f.close():
170 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000171
Brett Cannonb47243a2003-06-16 21:54:50 +0000172 def test_ismount(self):
173 self.assertIs(posixpath.ismount("/"), True)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100174 with warnings.catch_warnings():
175 warnings.simplefilter("ignore", DeprecationWarning)
176 self.assertIs(posixpath.ismount(b"/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400177
178 def test_ismount_non_existent(self):
179 # Non-existent mountpoint.
180 self.assertIs(posixpath.ismount(ABSTFN), False)
181 try:
182 os.mkdir(ABSTFN)
183 self.assertIs(posixpath.ismount(ABSTFN), False)
184 finally:
185 safe_rmdir(ABSTFN)
186
187 @unittest.skipUnless(support.can_symlink(),
188 "Test requires symlink support")
189 def test_ismount_symlinks(self):
190 # Symlinks are never mountpoints.
191 try:
192 os.symlink("/", ABSTFN)
193 self.assertIs(posixpath.ismount(ABSTFN), False)
194 finally:
195 os.unlink(ABSTFN)
196
197 @unittest.skipIf(posix is None, "Test requires posix module")
198 def test_ismount_different_device(self):
199 # Simulate the path being on a different device from its parent by
200 # mocking out st_dev.
201 save_lstat = os.lstat
202 def fake_lstat(path):
203 st_ino = 0
204 st_dev = 0
205 if path == ABSTFN:
206 st_dev = 1
207 st_ino = 1
208 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
209 try:
210 os.lstat = fake_lstat
211 self.assertIs(posixpath.ismount(ABSTFN), True)
212 finally:
213 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000214
Brett Cannonb47243a2003-06-16 21:54:50 +0000215 def test_expanduser(self):
216 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000217 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000218 try:
219 import pwd
220 except ImportError:
221 pass
222 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000223 self.assertIsInstance(posixpath.expanduser("~/"), str)
224 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000225 # if home directory == root directory, this test makes no sense
226 if posixpath.expanduser("~") != '/':
227 self.assertEqual(
228 posixpath.expanduser("~") + "/",
229 posixpath.expanduser("~/")
230 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000231 self.assertEqual(
232 posixpath.expanduser(b"~") + b"/",
233 posixpath.expanduser(b"~/")
234 )
Ezio Melottie9615932010-01-24 19:26:24 +0000235 self.assertIsInstance(posixpath.expanduser("~root/"), str)
236 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
237 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
238 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000239
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000240 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000241 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000242 self.assertEqual(posixpath.expanduser("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200243 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400244 # expanduser should fall back to using the password database
245 del env['HOME']
246 home = pwd.getpwuid(os.getuid()).pw_dir
Ezio Melottice82d572013-05-09 15:19:45 +0300247 # $HOME can end with a trailing /, so strip it (see #17809)
248 self.assertEqual(posixpath.expanduser("~"), home.rstrip("/"))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000249
Brett Cannonb47243a2003-06-16 21:54:50 +0000250 def test_normpath(self):
251 self.assertEqual(posixpath.normpath(""), ".")
252 self.assertEqual(posixpath.normpath("/"), "/")
253 self.assertEqual(posixpath.normpath("//"), "//")
254 self.assertEqual(posixpath.normpath("///"), "/")
255 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000256 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
257 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000258 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
259
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000260 self.assertEqual(posixpath.normpath(b""), b".")
261 self.assertEqual(posixpath.normpath(b"/"), b"/")
262 self.assertEqual(posixpath.normpath(b"//"), b"//")
263 self.assertEqual(posixpath.normpath(b"///"), b"/")
264 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
265 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
266 b"/foo/baz")
267 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
268 b"/foo/bar")
269
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200270 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200271 def test_realpath_curdir(self):
272 self.assertEqual(realpath('.'), os.getcwd())
273 self.assertEqual(realpath('./.'), os.getcwd())
274 self.assertEqual(realpath('/'.join(['.'] * 100)), os.getcwd())
275
276 self.assertEqual(realpath(b'.'), os.getcwdb())
277 self.assertEqual(realpath(b'./.'), os.getcwdb())
278 self.assertEqual(realpath(b'/'.join([b'.'] * 100)), os.getcwdb())
279
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200280 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200281 def test_realpath_pardir(self):
282 self.assertEqual(realpath('..'), dirname(os.getcwd()))
283 self.assertEqual(realpath('../..'), dirname(dirname(os.getcwd())))
284 self.assertEqual(realpath('/'.join(['..'] * 100)), '/')
285
286 self.assertEqual(realpath(b'..'), dirname(os.getcwdb()))
287 self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb())))
288 self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/')
289
Brian Curtin52173d42010-12-02 18:29:18 +0000290 @unittest.skipUnless(hasattr(os, "symlink"),
291 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000292 @skip_if_ABSTFN_contains_backslash
293 def test_realpath_basic(self):
294 # Basic operation.
295 try:
296 os.symlink(ABSTFN+"1", ABSTFN)
297 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
298 finally:
299 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000300
Brian Curtin52173d42010-12-02 18:29:18 +0000301 @unittest.skipUnless(hasattr(os, "symlink"),
302 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000303 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400304 def test_realpath_relative(self):
305 try:
306 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
307 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
308 finally:
309 support.unlink(ABSTFN)
310
311 @unittest.skipUnless(hasattr(os, "symlink"),
312 "Missing symlink implementation")
313 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000314 def test_realpath_symlink_loops(self):
315 # Bug #930024, return the path unchanged if we get into an infinite
316 # symlink loop.
317 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000318 os.symlink(ABSTFN, ABSTFN)
319 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000320
Brian Curtind40e6f72010-07-08 21:39:08 +0000321 os.symlink(ABSTFN+"1", ABSTFN+"2")
322 os.symlink(ABSTFN+"2", ABSTFN+"1")
323 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
324 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000325
Serhiy Storchakadf326912013-02-10 12:22:07 +0200326 self.assertEqual(realpath(ABSTFN+"1/x"), ABSTFN+"1/x")
327 self.assertEqual(realpath(ABSTFN+"1/.."), dirname(ABSTFN))
328 self.assertEqual(realpath(ABSTFN+"1/../x"), dirname(ABSTFN) + "/x")
329 os.symlink(ABSTFN+"x", ABSTFN+"y")
330 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "y"),
331 ABSTFN + "y")
332 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "1"),
333 ABSTFN + "1")
334
335 os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
336 self.assertEqual(realpath(ABSTFN+"a"), ABSTFN+"a/b")
337
338 os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
339 basename(ABSTFN) + "c", ABSTFN+"c")
340 self.assertEqual(realpath(ABSTFN+"c"), ABSTFN+"c")
341
Brian Curtind40e6f72010-07-08 21:39:08 +0000342 # Test using relative path as well.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300343 with support.change_cwd(dirname(ABSTFN)):
344 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
Brian Curtind40e6f72010-07-08 21:39:08 +0000345 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000346 support.unlink(ABSTFN)
347 support.unlink(ABSTFN+"1")
348 support.unlink(ABSTFN+"2")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200349 support.unlink(ABSTFN+"y")
350 support.unlink(ABSTFN+"c")
Ezio Melotti136726c2013-03-01 20:59:17 +0200351 support.unlink(ABSTFN+"a")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200352
353 @unittest.skipUnless(hasattr(os, "symlink"),
354 "Missing symlink implementation")
355 @skip_if_ABSTFN_contains_backslash
356 def test_realpath_repeated_indirect_symlinks(self):
357 # Issue #6975.
358 try:
359 os.mkdir(ABSTFN)
360 os.symlink('../' + basename(ABSTFN), ABSTFN + '/self')
361 os.symlink('self/self/self', ABSTFN + '/link')
362 self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN)
363 finally:
364 support.unlink(ABSTFN + '/self')
365 support.unlink(ABSTFN + '/link')
366 safe_rmdir(ABSTFN)
367
368 @unittest.skipUnless(hasattr(os, "symlink"),
369 "Missing symlink implementation")
370 @skip_if_ABSTFN_contains_backslash
371 def test_realpath_deep_recursion(self):
372 depth = 10
Serhiy Storchakadf326912013-02-10 12:22:07 +0200373 try:
374 os.mkdir(ABSTFN)
375 for i in range(depth):
376 os.symlink('/'.join(['%d' % i] * 10), ABSTFN + '/%d' % (i + 1))
377 os.symlink('.', ABSTFN + '/0')
378 self.assertEqual(realpath(ABSTFN + '/%d' % depth), ABSTFN)
379
380 # Test using relative path as well.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300381 with support.change_cwd(ABSTFN):
382 self.assertEqual(realpath('%d' % depth), ABSTFN)
Serhiy Storchakadf326912013-02-10 12:22:07 +0200383 finally:
Serhiy Storchakadf326912013-02-10 12:22:07 +0200384 for i in range(depth + 1):
385 support.unlink(ABSTFN + '/%d' % i)
386 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000387
Brian Curtin52173d42010-12-02 18:29:18 +0000388 @unittest.skipUnless(hasattr(os, "symlink"),
389 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000390 @skip_if_ABSTFN_contains_backslash
391 def test_realpath_resolve_parents(self):
392 # We also need to resolve any symlinks in the parents of a relative
393 # path passed to realpath. E.g.: current working directory is
394 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
395 # realpath("a"). This should return /usr/share/doc/a/.
396 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000397 os.mkdir(ABSTFN)
398 os.mkdir(ABSTFN + "/y")
399 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000400
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300401 with support.change_cwd(ABSTFN + "/k"):
402 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
Brian Curtind40e6f72010-07-08 21:39:08 +0000403 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000404 support.unlink(ABSTFN + "/k")
405 safe_rmdir(ABSTFN + "/y")
406 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000407
Brian Curtin52173d42010-12-02 18:29:18 +0000408 @unittest.skipUnless(hasattr(os, "symlink"),
409 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000410 @skip_if_ABSTFN_contains_backslash
411 def test_realpath_resolve_before_normalizing(self):
412 # Bug #990669: Symbolic links should be resolved before we
413 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
414 # in the following hierarchy:
415 # a/k/y
416 #
417 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
418 # then realpath("link-y/..") should return 'k', not 'a'.
419 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000420 os.mkdir(ABSTFN)
421 os.mkdir(ABSTFN + "/k")
422 os.mkdir(ABSTFN + "/k/y")
423 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000424
Brian Curtind40e6f72010-07-08 21:39:08 +0000425 # Absolute path.
426 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
427 # Relative path.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300428 with support.change_cwd(dirname(ABSTFN)):
429 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
430 ABSTFN + "/k")
Brian Curtind40e6f72010-07-08 21:39:08 +0000431 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000432 support.unlink(ABSTFN + "/link-y")
433 safe_rmdir(ABSTFN + "/k/y")
434 safe_rmdir(ABSTFN + "/k")
435 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000436
Brian Curtin52173d42010-12-02 18:29:18 +0000437 @unittest.skipUnless(hasattr(os, "symlink"),
438 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000439 @skip_if_ABSTFN_contains_backslash
440 def test_realpath_resolve_first(self):
441 # Bug #1213894: The first component of the path, if not absolute,
442 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000443
Brian Curtind40e6f72010-07-08 21:39:08 +0000444 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000445 os.mkdir(ABSTFN)
446 os.mkdir(ABSTFN + "/k")
447 os.symlink(ABSTFN, ABSTFN + "link")
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300448 with support.change_cwd(dirname(ABSTFN)):
449 base = basename(ABSTFN)
450 self.assertEqual(realpath(base + "link"), ABSTFN)
451 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
Brian Curtind40e6f72010-07-08 21:39:08 +0000452 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000453 support.unlink(ABSTFN + "link")
454 safe_rmdir(ABSTFN + "/k")
455 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000456
Guido van Rossumd8faa362007-04-27 19:54:29 +0000457 def test_relpath(self):
458 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
459 try:
460 curdir = os.path.split(os.getcwd())[-1]
461 self.assertRaises(ValueError, posixpath.relpath, "")
462 self.assertEqual(posixpath.relpath("a"), "a")
463 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
464 self.assertEqual(posixpath.relpath("a/b"), "a/b")
465 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
466 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000467 self.assertEqual(posixpath.relpath("a/b", "../c"),
468 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000469 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000470 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000471 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
472 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
473 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
474 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
475 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
476 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
477 self.assertEqual(posixpath.relpath("/", "/"), '.')
478 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
479 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000480 finally:
481 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000482
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000483 def test_relpath_bytes(self):
484 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
485 try:
486 curdir = os.path.split(os.getcwdb())[-1]
487 self.assertRaises(ValueError, posixpath.relpath, b"")
488 self.assertEqual(posixpath.relpath(b"a"), b"a")
489 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
490 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
491 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
492 self.assertEqual(posixpath.relpath(b"a", b"../b"),
493 b"../"+curdir+b"/a")
494 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
495 b"../"+curdir+b"/a/b")
496 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
497 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000498 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
499 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
500 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
501 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
502 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
503 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
504 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
505 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
506 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000507
508 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
509 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
510 finally:
511 os.getcwdb = real_getcwdb
512
Serhiy Storchaka38220932015-03-31 15:31:53 +0300513 def test_commonpath(self):
514 def check(paths, expected):
515 self.assertEqual(posixpath.commonpath(paths), expected)
516 self.assertEqual(posixpath.commonpath([os.fsencode(p) for p in paths]),
517 os.fsencode(expected))
518 def check_error(exc, paths):
519 self.assertRaises(exc, posixpath.commonpath, paths)
520 self.assertRaises(exc, posixpath.commonpath,
521 [os.fsencode(p) for p in paths])
522
523 self.assertRaises(ValueError, posixpath.commonpath, [])
524 check_error(ValueError, ['/usr', 'usr'])
525 check_error(ValueError, ['usr', '/usr'])
526
527 check(['/usr/local'], '/usr/local')
528 check(['/usr/local', '/usr/local'], '/usr/local')
529 check(['/usr/local/', '/usr/local'], '/usr/local')
530 check(['/usr/local/', '/usr/local/'], '/usr/local')
531 check(['/usr//local', '//usr/local'], '/usr/local')
532 check(['/usr/./local', '/./usr/local'], '/usr/local')
533 check(['/', '/dev'], '/')
534 check(['/usr', '/dev'], '/')
535 check(['/usr/lib/', '/usr/lib/python3'], '/usr/lib')
536 check(['/usr/lib/', '/usr/lib64/'], '/usr')
537
538 check(['/usr/lib', '/usr/lib64'], '/usr')
539 check(['/usr/lib/', '/usr/lib64'], '/usr')
540
541 check(['spam'], 'spam')
542 check(['spam', 'spam'], 'spam')
543 check(['spam', 'alot'], '')
544 check(['and/jam', 'and/spam'], 'and')
545 check(['and//jam', 'and/spam//'], 'and')
546 check(['and/./jam', './and/spam'], 'and')
547 check(['and/jam', 'and/spam', 'alot'], '')
548 check(['and/jam', 'and/spam', 'and'], 'and')
549
550 check([''], '')
551 check(['', 'spam/alot'], '')
552 check_error(ValueError, ['', '/spam/alot'])
553
554 self.assertRaises(TypeError, posixpath.commonpath,
555 [b'/usr/lib/', '/usr/lib/python3'])
556 self.assertRaises(TypeError, posixpath.commonpath,
557 [b'/usr/lib/', 'usr/lib/python3'])
558 self.assertRaises(TypeError, posixpath.commonpath,
559 [b'usr/lib/', '/usr/lib/python3'])
560 self.assertRaises(TypeError, posixpath.commonpath,
561 ['/usr/lib/', b'/usr/lib/python3'])
562 self.assertRaises(TypeError, posixpath.commonpath,
563 ['/usr/lib/', b'usr/lib/python3'])
564 self.assertRaises(TypeError, posixpath.commonpath,
565 ['usr/lib/', b'/usr/lib/python3'])
566
Florent Xiclunac9c79782010-03-08 12:24:53 +0000567
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200568class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000569 pathmodule = posixpath
570 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
571
572
Brett Cannonb47243a2003-06-16 21:54:50 +0000573if __name__=="__main__":
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200574 unittest.main()