blob: 9d204715916d6ce0ecbd71c5231849d7d77ce6e2 [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
Brian Curtind40e6f72010-07-08 21:39:08 +00004import sys
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01005import unittest
6import warnings
Georg Brandl89fad142010-03-14 10:23:39 +00007from posixpath import realpath, abspath, dirname, basename
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01008from test import support, test_genericpath
Johannes Gijsbers4ec40642004-08-14 15:01:53 +00009
Michael Foord07926f02011-03-16 17:19:16 -040010try:
11 import posix
12except ImportError:
13 posix = None
14
Johannes Gijsbers4ec40642004-08-14 15:01:53 +000015# An absolute path to a temporary filename for testing. We can't rely on TESTFN
16# being an absolute path, so we need this.
17
Benjamin Petersonee8712c2008-05-20 21:35:26 +000018ABSTFN = abspath(support.TESTFN)
Skip Montanaroe809b002000-07-12 00:20:08 +000019
Brian Curtind40e6f72010-07-08 21:39:08 +000020def skip_if_ABSTFN_contains_backslash(test):
21 """
22 On Windows, posixpath.abspath still returns paths with backslashes
23 instead of posix forward slashes. If this is the case, several tests
24 fail, so skip them.
25 """
26 found_backslash = '\\' in ABSTFN
27 msg = "ABSTFN is not a posix path - tests fail"
28 return [test, unittest.skip(msg)(test)][found_backslash]
29
Guido van Rossumd8faa362007-04-27 19:54:29 +000030def safe_rmdir(dirname):
31 try:
32 os.rmdir(dirname)
33 except OSError:
34 pass
35
Brett Cannonb47243a2003-06-16 21:54:50 +000036class PosixPathTest(unittest.TestCase):
Skip Montanaroe809b002000-07-12 00:20:08 +000037
Guido van Rossumd8faa362007-04-27 19:54:29 +000038 def setUp(self):
39 self.tearDown()
40
41 def tearDown(self):
42 for suffix in ["", "1", "2"]:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000043 support.unlink(support.TESTFN + suffix)
44 safe_rmdir(support.TESTFN + suffix)
Guido van Rossumd8faa362007-04-27 19:54:29 +000045
Brett Cannonb47243a2003-06-16 21:54:50 +000046 def test_join(self):
Guido van Rossumf0af3e32008-10-02 18:55:37 +000047 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"),
48 "/bar/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +000049 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
Guido van Rossumf0af3e32008-10-02 18:55:37 +000050 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"),
51 "/foo/bar/baz/")
52
53 self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"),
54 b"/bar/baz")
55 self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"),
56 b"/foo/bar/baz")
57 self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"),
58 b"/foo/bar/baz/")
Skip Montanaroe809b002000-07-12 00:20:08 +000059
Brett Cannonb47243a2003-06-16 21:54:50 +000060 def test_split(self):
61 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
62 self.assertEqual(posixpath.split("/"), ("/", ""))
63 self.assertEqual(posixpath.split("foo"), ("", "foo"))
64 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
65 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
66
Guido van Rossumf0af3e32008-10-02 18:55:37 +000067 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
68 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
69 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
70 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
71 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
72
Guido van Rossumd8faa362007-04-27 19:54:29 +000073 def splitextTest(self, path, filename, ext):
74 self.assertEqual(posixpath.splitext(path), (filename, ext))
75 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000076 self.assertEqual(posixpath.splitext("abc/" + path),
77 ("abc/" + filename, ext))
78 self.assertEqual(posixpath.splitext("abc.def/" + path),
79 ("abc.def/" + filename, ext))
80 self.assertEqual(posixpath.splitext("/abc.def/" + path),
81 ("/abc.def/" + filename, ext))
82 self.assertEqual(posixpath.splitext(path + "/"),
83 (filename + ext + "/", ""))
84
85 path = bytes(path, "ASCII")
86 filename = bytes(filename, "ASCII")
87 ext = bytes(ext, "ASCII")
88
89 self.assertEqual(posixpath.splitext(path), (filename, ext))
90 self.assertEqual(posixpath.splitext(b"/" + path),
91 (b"/" + filename, ext))
92 self.assertEqual(posixpath.splitext(b"abc/" + path),
93 (b"abc/" + filename, ext))
94 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
95 (b"abc.def/" + filename, ext))
96 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
97 (b"/abc.def/" + filename, ext))
98 self.assertEqual(posixpath.splitext(path + b"/"),
99 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +0000100
Guido van Rossumd8faa362007-04-27 19:54:29 +0000101 def test_splitext(self):
102 self.splitextTest("foo.bar", "foo", ".bar")
103 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
104 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
105 self.splitextTest(".csh.rc", ".csh", ".rc")
106 self.splitextTest("nodots", "nodots", "")
107 self.splitextTest(".cshrc", ".cshrc", "")
108 self.splitextTest("...manydots", "...manydots", "")
109 self.splitextTest("...manydots.ext", "...manydots", ".ext")
110 self.splitextTest(".", ".", "")
111 self.splitextTest("..", "..", "")
112 self.splitextTest("........", "........", "")
113 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000114
115 def test_isabs(self):
116 self.assertIs(posixpath.isabs(""), False)
117 self.assertIs(posixpath.isabs("/"), True)
118 self.assertIs(posixpath.isabs("/foo"), True)
119 self.assertIs(posixpath.isabs("/foo/bar"), True)
120 self.assertIs(posixpath.isabs("foo/bar"), False)
121
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000122 self.assertIs(posixpath.isabs(b""), False)
123 self.assertIs(posixpath.isabs(b"/"), True)
124 self.assertIs(posixpath.isabs(b"/foo"), True)
125 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
126 self.assertIs(posixpath.isabs(b"foo/bar"), False)
127
Brett Cannonb47243a2003-06-16 21:54:50 +0000128 def test_basename(self):
129 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
130 self.assertEqual(posixpath.basename("/"), "")
131 self.assertEqual(posixpath.basename("foo"), "foo")
132 self.assertEqual(posixpath.basename("////foo"), "foo")
133 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
134
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000135 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
136 self.assertEqual(posixpath.basename(b"/"), b"")
137 self.assertEqual(posixpath.basename(b"foo"), b"foo")
138 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
139 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
140
Brett Cannonb47243a2003-06-16 21:54:50 +0000141 def test_dirname(self):
142 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
143 self.assertEqual(posixpath.dirname("/"), "/")
144 self.assertEqual(posixpath.dirname("foo"), "")
145 self.assertEqual(posixpath.dirname("////foo"), "////")
146 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
147
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000148 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
149 self.assertEqual(posixpath.dirname(b"/"), b"/")
150 self.assertEqual(posixpath.dirname(b"foo"), b"")
151 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
152 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
153
Brett Cannonb47243a2003-06-16 21:54:50 +0000154 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000155 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400156 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000157 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000158 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000159 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000160 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000161 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000162 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000163 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
164 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
165 os.remove(support.TESTFN + "1")
166 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
167 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
168 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000169 finally:
170 if not f.close():
171 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000172
Brett Cannonb47243a2003-06-16 21:54:50 +0000173 def test_ismount(self):
174 self.assertIs(posixpath.ismount("/"), True)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100175 with warnings.catch_warnings():
176 warnings.simplefilter("ignore", DeprecationWarning)
177 self.assertIs(posixpath.ismount(b"/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400178
179 def test_ismount_non_existent(self):
180 # Non-existent mountpoint.
181 self.assertIs(posixpath.ismount(ABSTFN), False)
182 try:
183 os.mkdir(ABSTFN)
184 self.assertIs(posixpath.ismount(ABSTFN), False)
185 finally:
186 safe_rmdir(ABSTFN)
187
188 @unittest.skipUnless(support.can_symlink(),
189 "Test requires symlink support")
190 def test_ismount_symlinks(self):
191 # Symlinks are never mountpoints.
192 try:
193 os.symlink("/", ABSTFN)
194 self.assertIs(posixpath.ismount(ABSTFN), False)
195 finally:
196 os.unlink(ABSTFN)
197
198 @unittest.skipIf(posix is None, "Test requires posix module")
199 def test_ismount_different_device(self):
200 # Simulate the path being on a different device from its parent by
201 # mocking out st_dev.
202 save_lstat = os.lstat
203 def fake_lstat(path):
204 st_ino = 0
205 st_dev = 0
206 if path == ABSTFN:
207 st_dev = 1
208 st_ino = 1
209 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
210 try:
211 os.lstat = fake_lstat
212 self.assertIs(posixpath.ismount(ABSTFN), True)
213 finally:
214 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000215
Brett Cannonb47243a2003-06-16 21:54:50 +0000216 def test_expanduser(self):
217 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000218 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000219 try:
220 import pwd
221 except ImportError:
222 pass
223 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000224 self.assertIsInstance(posixpath.expanduser("~/"), str)
225 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000226 # if home directory == root directory, this test makes no sense
227 if posixpath.expanduser("~") != '/':
228 self.assertEqual(
229 posixpath.expanduser("~") + "/",
230 posixpath.expanduser("~/")
231 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000232 self.assertEqual(
233 posixpath.expanduser(b"~") + b"/",
234 posixpath.expanduser(b"~/")
235 )
Ezio Melottie9615932010-01-24 19:26:24 +0000236 self.assertIsInstance(posixpath.expanduser("~root/"), str)
237 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
238 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
239 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000240
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000241 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000242 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000243 self.assertEqual(posixpath.expanduser("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200244 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400245 # expanduser should fall back to using the password database
246 del env['HOME']
247 home = pwd.getpwuid(os.getuid()).pw_dir
Ezio Melottice82d572013-05-09 15:19:45 +0300248 # $HOME can end with a trailing /, so strip it (see #17809)
249 self.assertEqual(posixpath.expanduser("~"), home.rstrip("/"))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000250
Brett Cannonb47243a2003-06-16 21:54:50 +0000251 def test_normpath(self):
252 self.assertEqual(posixpath.normpath(""), ".")
253 self.assertEqual(posixpath.normpath("/"), "/")
254 self.assertEqual(posixpath.normpath("//"), "//")
255 self.assertEqual(posixpath.normpath("///"), "/")
256 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000257 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
258 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000259 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
260
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000261 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"///"), b"/")
265 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
266 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
267 b"/foo/baz")
268 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
269 b"/foo/bar")
270
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200271 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200272 def test_realpath_curdir(self):
273 self.assertEqual(realpath('.'), os.getcwd())
274 self.assertEqual(realpath('./.'), os.getcwd())
275 self.assertEqual(realpath('/'.join(['.'] * 100)), os.getcwd())
276
277 self.assertEqual(realpath(b'.'), os.getcwdb())
278 self.assertEqual(realpath(b'./.'), os.getcwdb())
279 self.assertEqual(realpath(b'/'.join([b'.'] * 100)), os.getcwdb())
280
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200281 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200282 def test_realpath_pardir(self):
283 self.assertEqual(realpath('..'), dirname(os.getcwd()))
284 self.assertEqual(realpath('../..'), dirname(dirname(os.getcwd())))
285 self.assertEqual(realpath('/'.join(['..'] * 100)), '/')
286
287 self.assertEqual(realpath(b'..'), dirname(os.getcwdb()))
288 self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb())))
289 self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/')
290
Brian Curtin52173d42010-12-02 18:29:18 +0000291 @unittest.skipUnless(hasattr(os, "symlink"),
292 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000293 @skip_if_ABSTFN_contains_backslash
294 def test_realpath_basic(self):
295 # Basic operation.
296 try:
297 os.symlink(ABSTFN+"1", ABSTFN)
298 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
299 finally:
300 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000301
Brian Curtin52173d42010-12-02 18:29:18 +0000302 @unittest.skipUnless(hasattr(os, "symlink"),
303 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000304 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400305 def test_realpath_relative(self):
306 try:
307 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
308 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
309 finally:
310 support.unlink(ABSTFN)
311
312 @unittest.skipUnless(hasattr(os, "symlink"),
313 "Missing symlink implementation")
314 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000315 def test_realpath_symlink_loops(self):
316 # Bug #930024, return the path unchanged if we get into an infinite
317 # symlink loop.
318 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000319 os.symlink(ABSTFN, ABSTFN)
320 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000321
Brian Curtind40e6f72010-07-08 21:39:08 +0000322 os.symlink(ABSTFN+"1", ABSTFN+"2")
323 os.symlink(ABSTFN+"2", ABSTFN+"1")
324 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
325 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000326
Serhiy Storchakadf326912013-02-10 12:22:07 +0200327 self.assertEqual(realpath(ABSTFN+"1/x"), ABSTFN+"1/x")
328 self.assertEqual(realpath(ABSTFN+"1/.."), dirname(ABSTFN))
329 self.assertEqual(realpath(ABSTFN+"1/../x"), dirname(ABSTFN) + "/x")
330 os.symlink(ABSTFN+"x", ABSTFN+"y")
331 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "y"),
332 ABSTFN + "y")
333 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "1"),
334 ABSTFN + "1")
335
336 os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
337 self.assertEqual(realpath(ABSTFN+"a"), ABSTFN+"a/b")
338
339 os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
340 basename(ABSTFN) + "c", ABSTFN+"c")
341 self.assertEqual(realpath(ABSTFN+"c"), ABSTFN+"c")
342
Brian Curtind40e6f72010-07-08 21:39:08 +0000343 # Test using relative path as well.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300344 with support.change_cwd(dirname(ABSTFN)):
345 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
Brian Curtind40e6f72010-07-08 21:39:08 +0000346 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000347 support.unlink(ABSTFN)
348 support.unlink(ABSTFN+"1")
349 support.unlink(ABSTFN+"2")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200350 support.unlink(ABSTFN+"y")
351 support.unlink(ABSTFN+"c")
Ezio Melotti136726c2013-03-01 20:59:17 +0200352 support.unlink(ABSTFN+"a")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200353
354 @unittest.skipUnless(hasattr(os, "symlink"),
355 "Missing symlink implementation")
356 @skip_if_ABSTFN_contains_backslash
357 def test_realpath_repeated_indirect_symlinks(self):
358 # Issue #6975.
359 try:
360 os.mkdir(ABSTFN)
361 os.symlink('../' + basename(ABSTFN), ABSTFN + '/self')
362 os.symlink('self/self/self', ABSTFN + '/link')
363 self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN)
364 finally:
365 support.unlink(ABSTFN + '/self')
366 support.unlink(ABSTFN + '/link')
367 safe_rmdir(ABSTFN)
368
369 @unittest.skipUnless(hasattr(os, "symlink"),
370 "Missing symlink implementation")
371 @skip_if_ABSTFN_contains_backslash
372 def test_realpath_deep_recursion(self):
373 depth = 10
Serhiy Storchakadf326912013-02-10 12:22:07 +0200374 try:
375 os.mkdir(ABSTFN)
376 for i in range(depth):
377 os.symlink('/'.join(['%d' % i] * 10), ABSTFN + '/%d' % (i + 1))
378 os.symlink('.', ABSTFN + '/0')
379 self.assertEqual(realpath(ABSTFN + '/%d' % depth), ABSTFN)
380
381 # Test using relative path as well.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300382 with support.change_cwd(ABSTFN):
383 self.assertEqual(realpath('%d' % depth), ABSTFN)
Serhiy Storchakadf326912013-02-10 12:22:07 +0200384 finally:
Serhiy Storchakadf326912013-02-10 12:22:07 +0200385 for i in range(depth + 1):
386 support.unlink(ABSTFN + '/%d' % i)
387 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000388
Brian Curtin52173d42010-12-02 18:29:18 +0000389 @unittest.skipUnless(hasattr(os, "symlink"),
390 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000391 @skip_if_ABSTFN_contains_backslash
392 def test_realpath_resolve_parents(self):
393 # We also need to resolve any symlinks in the parents of a relative
394 # path passed to realpath. E.g.: current working directory is
395 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
396 # realpath("a"). This should return /usr/share/doc/a/.
397 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000398 os.mkdir(ABSTFN)
399 os.mkdir(ABSTFN + "/y")
400 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000401
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300402 with support.change_cwd(ABSTFN + "/k"):
403 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
Brian Curtind40e6f72010-07-08 21:39:08 +0000404 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000405 support.unlink(ABSTFN + "/k")
406 safe_rmdir(ABSTFN + "/y")
407 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000408
Brian Curtin52173d42010-12-02 18:29:18 +0000409 @unittest.skipUnless(hasattr(os, "symlink"),
410 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000411 @skip_if_ABSTFN_contains_backslash
412 def test_realpath_resolve_before_normalizing(self):
413 # Bug #990669: Symbolic links should be resolved before we
414 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
415 # in the following hierarchy:
416 # a/k/y
417 #
418 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
419 # then realpath("link-y/..") should return 'k', not 'a'.
420 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000421 os.mkdir(ABSTFN)
422 os.mkdir(ABSTFN + "/k")
423 os.mkdir(ABSTFN + "/k/y")
424 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000425
Brian Curtind40e6f72010-07-08 21:39:08 +0000426 # Absolute path.
427 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
428 # Relative path.
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300429 with support.change_cwd(dirname(ABSTFN)):
430 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
431 ABSTFN + "/k")
Brian Curtind40e6f72010-07-08 21:39:08 +0000432 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000433 support.unlink(ABSTFN + "/link-y")
434 safe_rmdir(ABSTFN + "/k/y")
435 safe_rmdir(ABSTFN + "/k")
436 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000437
Brian Curtin52173d42010-12-02 18:29:18 +0000438 @unittest.skipUnless(hasattr(os, "symlink"),
439 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000440 @skip_if_ABSTFN_contains_backslash
441 def test_realpath_resolve_first(self):
442 # Bug #1213894: The first component of the path, if not absolute,
443 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000444
Brian Curtind40e6f72010-07-08 21:39:08 +0000445 try:
Brian Curtind40e6f72010-07-08 21:39:08 +0000446 os.mkdir(ABSTFN)
447 os.mkdir(ABSTFN + "/k")
448 os.symlink(ABSTFN, ABSTFN + "link")
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +0300449 with support.change_cwd(dirname(ABSTFN)):
450 base = basename(ABSTFN)
451 self.assertEqual(realpath(base + "link"), ABSTFN)
452 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
Brian Curtind40e6f72010-07-08 21:39:08 +0000453 finally:
Brian Curtind40e6f72010-07-08 21:39:08 +0000454 support.unlink(ABSTFN + "link")
455 safe_rmdir(ABSTFN + "/k")
456 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000457
Guido van Rossumd8faa362007-04-27 19:54:29 +0000458 def test_relpath(self):
459 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
460 try:
461 curdir = os.path.split(os.getcwd())[-1]
462 self.assertRaises(ValueError, posixpath.relpath, "")
463 self.assertEqual(posixpath.relpath("a"), "a")
464 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
465 self.assertEqual(posixpath.relpath("a/b"), "a/b")
466 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
467 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000468 self.assertEqual(posixpath.relpath("a/b", "../c"),
469 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000470 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000471 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000472 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
473 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
474 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
475 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
476 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
477 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
478 self.assertEqual(posixpath.relpath("/", "/"), '.')
479 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
480 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000481 finally:
482 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000483
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000484 def test_relpath_bytes(self):
485 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
486 try:
487 curdir = os.path.split(os.getcwdb())[-1]
488 self.assertRaises(ValueError, posixpath.relpath, b"")
489 self.assertEqual(posixpath.relpath(b"a"), b"a")
490 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
491 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
492 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
493 self.assertEqual(posixpath.relpath(b"a", b"../b"),
494 b"../"+curdir+b"/a")
495 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
496 b"../"+curdir+b"/a/b")
497 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
498 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000499 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
500 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
501 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
502 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
503 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
504 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
505 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
506 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
507 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000508
509 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
510 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
511 finally:
512 os.getcwdb = real_getcwdb
513
Serhiy Storchaka38220932015-03-31 15:31:53 +0300514 def test_commonpath(self):
515 def check(paths, expected):
516 self.assertEqual(posixpath.commonpath(paths), expected)
517 self.assertEqual(posixpath.commonpath([os.fsencode(p) for p in paths]),
518 os.fsencode(expected))
519 def check_error(exc, paths):
520 self.assertRaises(exc, posixpath.commonpath, paths)
521 self.assertRaises(exc, posixpath.commonpath,
522 [os.fsencode(p) for p in paths])
523
524 self.assertRaises(ValueError, posixpath.commonpath, [])
525 check_error(ValueError, ['/usr', 'usr'])
526 check_error(ValueError, ['usr', '/usr'])
527
528 check(['/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(['/usr/./local', '/./usr/local'], '/usr/local')
534 check(['/', '/dev'], '/')
535 check(['/usr', '/dev'], '/')
536 check(['/usr/lib/', '/usr/lib/python3'], '/usr/lib')
537 check(['/usr/lib/', '/usr/lib64/'], '/usr')
538
539 check(['/usr/lib', '/usr/lib64'], '/usr')
540 check(['/usr/lib/', '/usr/lib64'], '/usr')
541
542 check(['spam'], 'spam')
543 check(['spam', 'spam'], 'spam')
544 check(['spam', 'alot'], '')
545 check(['and/jam', 'and/spam'], 'and')
546 check(['and//jam', 'and/spam//'], 'and')
547 check(['and/./jam', './and/spam'], 'and')
548 check(['and/jam', 'and/spam', 'alot'], '')
549 check(['and/jam', 'and/spam', 'and'], 'and')
550
551 check([''], '')
552 check(['', 'spam/alot'], '')
553 check_error(ValueError, ['', '/spam/alot'])
554
555 self.assertRaises(TypeError, posixpath.commonpath,
556 [b'/usr/lib/', '/usr/lib/python3'])
557 self.assertRaises(TypeError, posixpath.commonpath,
558 [b'/usr/lib/', 'usr/lib/python3'])
559 self.assertRaises(TypeError, posixpath.commonpath,
560 [b'usr/lib/', '/usr/lib/python3'])
561 self.assertRaises(TypeError, posixpath.commonpath,
562 ['/usr/lib/', b'/usr/lib/python3'])
563 self.assertRaises(TypeError, posixpath.commonpath,
564 ['/usr/lib/', b'usr/lib/python3'])
565 self.assertRaises(TypeError, posixpath.commonpath,
566 ['usr/lib/', b'/usr/lib/python3'])
567
Florent Xiclunac9c79782010-03-08 12:24:53 +0000568
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200569class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000570 pathmodule = posixpath
571 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
572
573
Brett Cannonb47243a2003-06-16 21:54:50 +0000574if __name__=="__main__":
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200575 unittest.main()