blob: 1f050505a7931f1331a7a60b9581f2fc6dc7effd [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
Hynek Schlawackc5a45662012-07-17 13:05:43 +020060 def check_error_msg(list_of_args, msg):
61 """Check posixpath.join raises friendly TypeErrors."""
62 for args in (item for perm in list_of_args
63 for item in itertools.permutations(perm)):
Hynek Schlawack7cdc2bd2012-07-17 10:48:19 +020064 with self.assertRaises(TypeError) as cm:
65 posixpath.join(*args)
Hynek Schlawackc5a45662012-07-17 13:05:43 +020066 self.assertEqual(msg, cm.exception.args[0])
Hynek Schlawack7cdc2bd2012-07-17 10:48:19 +020067
Hynek Schlawackc5a45662012-07-17 13:05:43 +020068 check_error_msg([[b'bytes', 'str'], [bytearray(b'bytes'), 'str']],
69 "Can't mix strings and bytes in path components.")
70 # regression, see #15377
71 with self.assertRaises(TypeError) as cm:
Hynek Schlawack0b350c62012-07-17 14:28:44 +020072 posixpath.join(None, 'str')
Hynek Schlawackc5a45662012-07-17 13:05:43 +020073 self.assertNotEqual("Can't mix strings and bytes in path components.",
74 cm.exception.args[0])
Skip Montanaroe809b002000-07-12 00:20:08 +000075
Brett Cannonb47243a2003-06-16 21:54:50 +000076 def test_split(self):
77 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
78 self.assertEqual(posixpath.split("/"), ("/", ""))
79 self.assertEqual(posixpath.split("foo"), ("", "foo"))
80 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
81 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
82
Guido van Rossumf0af3e32008-10-02 18:55:37 +000083 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
84 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
85 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
86 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
87 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
88
Guido van Rossumd8faa362007-04-27 19:54:29 +000089 def splitextTest(self, path, filename, ext):
90 self.assertEqual(posixpath.splitext(path), (filename, ext))
91 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000092 self.assertEqual(posixpath.splitext("abc/" + path),
93 ("abc/" + filename, ext))
94 self.assertEqual(posixpath.splitext("abc.def/" + path),
95 ("abc.def/" + filename, ext))
96 self.assertEqual(posixpath.splitext("/abc.def/" + path),
97 ("/abc.def/" + filename, ext))
98 self.assertEqual(posixpath.splitext(path + "/"),
99 (filename + ext + "/", ""))
100
101 path = bytes(path, "ASCII")
102 filename = bytes(filename, "ASCII")
103 ext = bytes(ext, "ASCII")
104
105 self.assertEqual(posixpath.splitext(path), (filename, ext))
106 self.assertEqual(posixpath.splitext(b"/" + path),
107 (b"/" + filename, ext))
108 self.assertEqual(posixpath.splitext(b"abc/" + path),
109 (b"abc/" + filename, ext))
110 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
111 (b"abc.def/" + filename, ext))
112 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
113 (b"/abc.def/" + filename, ext))
114 self.assertEqual(posixpath.splitext(path + b"/"),
115 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +0000116
Guido van Rossumd8faa362007-04-27 19:54:29 +0000117 def test_splitext(self):
118 self.splitextTest("foo.bar", "foo", ".bar")
119 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
120 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
121 self.splitextTest(".csh.rc", ".csh", ".rc")
122 self.splitextTest("nodots", "nodots", "")
123 self.splitextTest(".cshrc", ".cshrc", "")
124 self.splitextTest("...manydots", "...manydots", "")
125 self.splitextTest("...manydots.ext", "...manydots", ".ext")
126 self.splitextTest(".", ".", "")
127 self.splitextTest("..", "..", "")
128 self.splitextTest("........", "........", "")
129 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000130
131 def test_isabs(self):
132 self.assertIs(posixpath.isabs(""), False)
133 self.assertIs(posixpath.isabs("/"), True)
134 self.assertIs(posixpath.isabs("/foo"), True)
135 self.assertIs(posixpath.isabs("/foo/bar"), True)
136 self.assertIs(posixpath.isabs("foo/bar"), False)
137
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000138 self.assertIs(posixpath.isabs(b""), False)
139 self.assertIs(posixpath.isabs(b"/"), True)
140 self.assertIs(posixpath.isabs(b"/foo"), True)
141 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
142 self.assertIs(posixpath.isabs(b"foo/bar"), False)
143
Brett Cannonb47243a2003-06-16 21:54:50 +0000144 def test_basename(self):
145 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
146 self.assertEqual(posixpath.basename("/"), "")
147 self.assertEqual(posixpath.basename("foo"), "foo")
148 self.assertEqual(posixpath.basename("////foo"), "foo")
149 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
150
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000151 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
152 self.assertEqual(posixpath.basename(b"/"), b"")
153 self.assertEqual(posixpath.basename(b"foo"), b"foo")
154 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
155 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
156
Brett Cannonb47243a2003-06-16 21:54:50 +0000157 def test_dirname(self):
158 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
159 self.assertEqual(posixpath.dirname("/"), "/")
160 self.assertEqual(posixpath.dirname("foo"), "")
161 self.assertEqual(posixpath.dirname("////foo"), "////")
162 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
163
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000164 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
165 self.assertEqual(posixpath.dirname(b"/"), b"/")
166 self.assertEqual(posixpath.dirname(b"foo"), b"")
167 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
168 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
169
Brett Cannonb47243a2003-06-16 21:54:50 +0000170 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000171 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400172 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000173 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000174 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000175 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000176 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000177 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000178 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000179 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
180 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
181 os.remove(support.TESTFN + "1")
182 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
183 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
184 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000185 finally:
186 if not f.close():
187 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000188
Brett Cannonb47243a2003-06-16 21:54:50 +0000189 def test_ismount(self):
190 self.assertIs(posixpath.ismount("/"), True)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100191 with warnings.catch_warnings():
192 warnings.simplefilter("ignore", DeprecationWarning)
193 self.assertIs(posixpath.ismount(b"/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400194
195 def test_ismount_non_existent(self):
196 # Non-existent mountpoint.
197 self.assertIs(posixpath.ismount(ABSTFN), False)
198 try:
199 os.mkdir(ABSTFN)
200 self.assertIs(posixpath.ismount(ABSTFN), False)
201 finally:
202 safe_rmdir(ABSTFN)
203
204 @unittest.skipUnless(support.can_symlink(),
205 "Test requires symlink support")
206 def test_ismount_symlinks(self):
207 # Symlinks are never mountpoints.
208 try:
209 os.symlink("/", ABSTFN)
210 self.assertIs(posixpath.ismount(ABSTFN), False)
211 finally:
212 os.unlink(ABSTFN)
213
214 @unittest.skipIf(posix is None, "Test requires posix module")
215 def test_ismount_different_device(self):
216 # Simulate the path being on a different device from its parent by
217 # mocking out st_dev.
218 save_lstat = os.lstat
219 def fake_lstat(path):
220 st_ino = 0
221 st_dev = 0
222 if path == ABSTFN:
223 st_dev = 1
224 st_ino = 1
225 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
226 try:
227 os.lstat = fake_lstat
228 self.assertIs(posixpath.ismount(ABSTFN), True)
229 finally:
230 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000231
Brett Cannonb47243a2003-06-16 21:54:50 +0000232 def test_expanduser(self):
233 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000234 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000235 try:
236 import pwd
237 except ImportError:
238 pass
239 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000240 self.assertIsInstance(posixpath.expanduser("~/"), str)
241 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000242 # if home directory == root directory, this test makes no sense
243 if posixpath.expanduser("~") != '/':
244 self.assertEqual(
245 posixpath.expanduser("~") + "/",
246 posixpath.expanduser("~/")
247 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000248 self.assertEqual(
249 posixpath.expanduser(b"~") + b"/",
250 posixpath.expanduser(b"~/")
251 )
Ezio Melottie9615932010-01-24 19:26:24 +0000252 self.assertIsInstance(posixpath.expanduser("~root/"), str)
253 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
254 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
255 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000256
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000257 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000258 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000259 self.assertEqual(posixpath.expanduser("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200260 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400261 # expanduser should fall back to using the password database
262 del env['HOME']
263 home = pwd.getpwuid(os.getuid()).pw_dir
264 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000265
Brett Cannonb47243a2003-06-16 21:54:50 +0000266 def test_normpath(self):
267 self.assertEqual(posixpath.normpath(""), ".")
268 self.assertEqual(posixpath.normpath("/"), "/")
269 self.assertEqual(posixpath.normpath("//"), "//")
270 self.assertEqual(posixpath.normpath("///"), "/")
271 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000272 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
273 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000274 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
275
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000276 self.assertEqual(posixpath.normpath(b""), b".")
277 self.assertEqual(posixpath.normpath(b"/"), b"/")
278 self.assertEqual(posixpath.normpath(b"//"), b"//")
279 self.assertEqual(posixpath.normpath(b"///"), b"/")
280 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
281 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
282 b"/foo/baz")
283 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
284 b"/foo/bar")
285
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200286 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200287 def test_realpath_curdir(self):
288 self.assertEqual(realpath('.'), os.getcwd())
289 self.assertEqual(realpath('./.'), os.getcwd())
290 self.assertEqual(realpath('/'.join(['.'] * 100)), os.getcwd())
291
292 self.assertEqual(realpath(b'.'), os.getcwdb())
293 self.assertEqual(realpath(b'./.'), os.getcwdb())
294 self.assertEqual(realpath(b'/'.join([b'.'] * 100)), os.getcwdb())
295
Serhiy Storchaka1548ed62013-02-18 13:32:30 +0200296 @skip_if_ABSTFN_contains_backslash
Serhiy Storchaka467393d2013-02-18 12:21:04 +0200297 def test_realpath_pardir(self):
298 self.assertEqual(realpath('..'), dirname(os.getcwd()))
299 self.assertEqual(realpath('../..'), dirname(dirname(os.getcwd())))
300 self.assertEqual(realpath('/'.join(['..'] * 100)), '/')
301
302 self.assertEqual(realpath(b'..'), dirname(os.getcwdb()))
303 self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb())))
304 self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/')
305
Brian Curtin52173d42010-12-02 18:29:18 +0000306 @unittest.skipUnless(hasattr(os, "symlink"),
307 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000308 @skip_if_ABSTFN_contains_backslash
309 def test_realpath_basic(self):
310 # Basic operation.
311 try:
312 os.symlink(ABSTFN+"1", ABSTFN)
313 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
314 finally:
315 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000316
Brian Curtin52173d42010-12-02 18:29:18 +0000317 @unittest.skipUnless(hasattr(os, "symlink"),
318 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000319 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400320 def test_realpath_relative(self):
321 try:
322 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
323 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
324 finally:
325 support.unlink(ABSTFN)
326
327 @unittest.skipUnless(hasattr(os, "symlink"),
328 "Missing symlink implementation")
329 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000330 def test_realpath_symlink_loops(self):
331 # Bug #930024, return the path unchanged if we get into an infinite
332 # symlink loop.
333 try:
334 old_path = abspath('.')
335 os.symlink(ABSTFN, ABSTFN)
336 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000337
Brian Curtind40e6f72010-07-08 21:39:08 +0000338 os.symlink(ABSTFN+"1", ABSTFN+"2")
339 os.symlink(ABSTFN+"2", ABSTFN+"1")
340 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
341 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000342
Serhiy Storchakadf326912013-02-10 12:22:07 +0200343 self.assertEqual(realpath(ABSTFN+"1/x"), ABSTFN+"1/x")
344 self.assertEqual(realpath(ABSTFN+"1/.."), dirname(ABSTFN))
345 self.assertEqual(realpath(ABSTFN+"1/../x"), dirname(ABSTFN) + "/x")
346 os.symlink(ABSTFN+"x", ABSTFN+"y")
347 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "y"),
348 ABSTFN + "y")
349 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "1"),
350 ABSTFN + "1")
351
352 os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
353 self.assertEqual(realpath(ABSTFN+"a"), ABSTFN+"a/b")
354
355 os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
356 basename(ABSTFN) + "c", ABSTFN+"c")
357 self.assertEqual(realpath(ABSTFN+"c"), ABSTFN+"c")
358
Brian Curtind40e6f72010-07-08 21:39:08 +0000359 # Test using relative path as well.
360 os.chdir(dirname(ABSTFN))
361 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
362 finally:
363 os.chdir(old_path)
364 support.unlink(ABSTFN)
365 support.unlink(ABSTFN+"1")
366 support.unlink(ABSTFN+"2")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200367 support.unlink(ABSTFN+"y")
368 support.unlink(ABSTFN+"c")
Ezio Melotti136726c2013-03-01 20:59:17 +0200369 support.unlink(ABSTFN+"a")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200370
371 @unittest.skipUnless(hasattr(os, "symlink"),
372 "Missing symlink implementation")
373 @skip_if_ABSTFN_contains_backslash
374 def test_realpath_repeated_indirect_symlinks(self):
375 # Issue #6975.
376 try:
377 os.mkdir(ABSTFN)
378 os.symlink('../' + basename(ABSTFN), ABSTFN + '/self')
379 os.symlink('self/self/self', ABSTFN + '/link')
380 self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN)
381 finally:
382 support.unlink(ABSTFN + '/self')
383 support.unlink(ABSTFN + '/link')
384 safe_rmdir(ABSTFN)
385
386 @unittest.skipUnless(hasattr(os, "symlink"),
387 "Missing symlink implementation")
388 @skip_if_ABSTFN_contains_backslash
389 def test_realpath_deep_recursion(self):
390 depth = 10
391 old_path = abspath('.')
392 try:
393 os.mkdir(ABSTFN)
394 for i in range(depth):
395 os.symlink('/'.join(['%d' % i] * 10), ABSTFN + '/%d' % (i + 1))
396 os.symlink('.', ABSTFN + '/0')
397 self.assertEqual(realpath(ABSTFN + '/%d' % depth), ABSTFN)
398
399 # Test using relative path as well.
400 os.chdir(ABSTFN)
401 self.assertEqual(realpath('%d' % depth), ABSTFN)
402 finally:
403 os.chdir(old_path)
404 for i in range(depth + 1):
405 support.unlink(ABSTFN + '/%d' % i)
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_parents(self):
412 # We also need to resolve any symlinks in the parents of a relative
413 # path passed to realpath. E.g.: current working directory is
414 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
415 # realpath("a"). This should return /usr/share/doc/a/.
416 try:
417 old_path = abspath('.')
418 os.mkdir(ABSTFN)
419 os.mkdir(ABSTFN + "/y")
420 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000421
Brian Curtind40e6f72010-07-08 21:39:08 +0000422 os.chdir(ABSTFN + "/k")
423 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
424 finally:
425 os.chdir(old_path)
426 support.unlink(ABSTFN + "/k")
427 safe_rmdir(ABSTFN + "/y")
428 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000429
Brian Curtin52173d42010-12-02 18:29:18 +0000430 @unittest.skipUnless(hasattr(os, "symlink"),
431 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000432 @skip_if_ABSTFN_contains_backslash
433 def test_realpath_resolve_before_normalizing(self):
434 # Bug #990669: Symbolic links should be resolved before we
435 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
436 # in the following hierarchy:
437 # a/k/y
438 #
439 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
440 # then realpath("link-y/..") should return 'k', not 'a'.
441 try:
442 old_path = abspath('.')
443 os.mkdir(ABSTFN)
444 os.mkdir(ABSTFN + "/k")
445 os.mkdir(ABSTFN + "/k/y")
446 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000447
Brian Curtind40e6f72010-07-08 21:39:08 +0000448 # Absolute path.
449 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
450 # Relative path.
451 os.chdir(dirname(ABSTFN))
452 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
453 ABSTFN + "/k")
454 finally:
455 os.chdir(old_path)
456 support.unlink(ABSTFN + "/link-y")
457 safe_rmdir(ABSTFN + "/k/y")
458 safe_rmdir(ABSTFN + "/k")
459 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000460
Brian Curtin52173d42010-12-02 18:29:18 +0000461 @unittest.skipUnless(hasattr(os, "symlink"),
462 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000463 @skip_if_ABSTFN_contains_backslash
464 def test_realpath_resolve_first(self):
465 # Bug #1213894: The first component of the path, if not absolute,
466 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000467
Brian Curtind40e6f72010-07-08 21:39:08 +0000468 try:
469 old_path = abspath('.')
470 os.mkdir(ABSTFN)
471 os.mkdir(ABSTFN + "/k")
472 os.symlink(ABSTFN, ABSTFN + "link")
473 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000474
Brian Curtind40e6f72010-07-08 21:39:08 +0000475 base = basename(ABSTFN)
476 self.assertEqual(realpath(base + "link"), ABSTFN)
477 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
478 finally:
479 os.chdir(old_path)
480 support.unlink(ABSTFN + "link")
481 safe_rmdir(ABSTFN + "/k")
482 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000483
Guido van Rossumd8faa362007-04-27 19:54:29 +0000484 def test_relpath(self):
485 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
486 try:
487 curdir = os.path.split(os.getcwd())[-1]
488 self.assertRaises(ValueError, posixpath.relpath, "")
489 self.assertEqual(posixpath.relpath("a"), "a")
490 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
491 self.assertEqual(posixpath.relpath("a/b"), "a/b")
492 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
493 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000494 self.assertEqual(posixpath.relpath("a/b", "../c"),
495 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000496 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000497 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000498 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
499 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
500 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
501 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
502 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
503 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
504 self.assertEqual(posixpath.relpath("/", "/"), '.')
505 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
506 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000507 finally:
508 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000509
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000510 def test_relpath_bytes(self):
511 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
512 try:
513 curdir = os.path.split(os.getcwdb())[-1]
514 self.assertRaises(ValueError, posixpath.relpath, b"")
515 self.assertEqual(posixpath.relpath(b"a"), b"a")
516 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
517 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
518 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
519 self.assertEqual(posixpath.relpath(b"a", b"../b"),
520 b"../"+curdir+b"/a")
521 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
522 b"../"+curdir+b"/a/b")
523 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
524 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000525 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
526 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
527 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
528 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
529 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
530 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
531 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
532 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
533 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000534
535 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
536 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
537 finally:
538 os.getcwdb = real_getcwdb
539
Florent Xiclunac9c79782010-03-08 12:24:53 +0000540
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200541class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000542 pathmodule = posixpath
543 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
544
545
Brett Cannonb47243a2003-06-16 21:54:50 +0000546if __name__=="__main__":
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200547 unittest.main()