blob: b2454794e5bda50ad5c4fa56b80fe0d4fb59816e [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:
319 old_path = abspath('.')
320 os.symlink(ABSTFN, ABSTFN)
321 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000322
Brian Curtind40e6f72010-07-08 21:39:08 +0000323 os.symlink(ABSTFN+"1", ABSTFN+"2")
324 os.symlink(ABSTFN+"2", ABSTFN+"1")
325 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
326 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000327
Serhiy Storchakadf326912013-02-10 12:22:07 +0200328 self.assertEqual(realpath(ABSTFN+"1/x"), ABSTFN+"1/x")
329 self.assertEqual(realpath(ABSTFN+"1/.."), dirname(ABSTFN))
330 self.assertEqual(realpath(ABSTFN+"1/../x"), dirname(ABSTFN) + "/x")
331 os.symlink(ABSTFN+"x", ABSTFN+"y")
332 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "y"),
333 ABSTFN + "y")
334 self.assertEqual(realpath(ABSTFN+"1/../" + basename(ABSTFN) + "1"),
335 ABSTFN + "1")
336
337 os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
338 self.assertEqual(realpath(ABSTFN+"a"), ABSTFN+"a/b")
339
340 os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
341 basename(ABSTFN) + "c", ABSTFN+"c")
342 self.assertEqual(realpath(ABSTFN+"c"), ABSTFN+"c")
343
Brian Curtind40e6f72010-07-08 21:39:08 +0000344 # Test using relative path as well.
345 os.chdir(dirname(ABSTFN))
346 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
347 finally:
348 os.chdir(old_path)
349 support.unlink(ABSTFN)
350 support.unlink(ABSTFN+"1")
351 support.unlink(ABSTFN+"2")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200352 support.unlink(ABSTFN+"y")
353 support.unlink(ABSTFN+"c")
Ezio Melotti136726c2013-03-01 20:59:17 +0200354 support.unlink(ABSTFN+"a")
Serhiy Storchakadf326912013-02-10 12:22:07 +0200355
356 @unittest.skipUnless(hasattr(os, "symlink"),
357 "Missing symlink implementation")
358 @skip_if_ABSTFN_contains_backslash
359 def test_realpath_repeated_indirect_symlinks(self):
360 # Issue #6975.
361 try:
362 os.mkdir(ABSTFN)
363 os.symlink('../' + basename(ABSTFN), ABSTFN + '/self')
364 os.symlink('self/self/self', ABSTFN + '/link')
365 self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN)
366 finally:
367 support.unlink(ABSTFN + '/self')
368 support.unlink(ABSTFN + '/link')
369 safe_rmdir(ABSTFN)
370
371 @unittest.skipUnless(hasattr(os, "symlink"),
372 "Missing symlink implementation")
373 @skip_if_ABSTFN_contains_backslash
374 def test_realpath_deep_recursion(self):
375 depth = 10
376 old_path = abspath('.')
377 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.
385 os.chdir(ABSTFN)
386 self.assertEqual(realpath('%d' % depth), ABSTFN)
387 finally:
388 os.chdir(old_path)
389 for i in range(depth + 1):
390 support.unlink(ABSTFN + '/%d' % i)
391 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000392
Brian Curtin52173d42010-12-02 18:29:18 +0000393 @unittest.skipUnless(hasattr(os, "symlink"),
394 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000395 @skip_if_ABSTFN_contains_backslash
396 def test_realpath_resolve_parents(self):
397 # We also need to resolve any symlinks in the parents of a relative
398 # path passed to realpath. E.g.: current working directory is
399 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
400 # realpath("a"). This should return /usr/share/doc/a/.
401 try:
402 old_path = abspath('.')
403 os.mkdir(ABSTFN)
404 os.mkdir(ABSTFN + "/y")
405 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000406
Brian Curtind40e6f72010-07-08 21:39:08 +0000407 os.chdir(ABSTFN + "/k")
408 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
409 finally:
410 os.chdir(old_path)
411 support.unlink(ABSTFN + "/k")
412 safe_rmdir(ABSTFN + "/y")
413 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000414
Brian Curtin52173d42010-12-02 18:29:18 +0000415 @unittest.skipUnless(hasattr(os, "symlink"),
416 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000417 @skip_if_ABSTFN_contains_backslash
418 def test_realpath_resolve_before_normalizing(self):
419 # Bug #990669: Symbolic links should be resolved before we
420 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
421 # in the following hierarchy:
422 # a/k/y
423 #
424 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
425 # then realpath("link-y/..") should return 'k', not 'a'.
426 try:
427 old_path = abspath('.')
428 os.mkdir(ABSTFN)
429 os.mkdir(ABSTFN + "/k")
430 os.mkdir(ABSTFN + "/k/y")
431 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000432
Brian Curtind40e6f72010-07-08 21:39:08 +0000433 # Absolute path.
434 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
435 # Relative path.
436 os.chdir(dirname(ABSTFN))
437 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
438 ABSTFN + "/k")
439 finally:
440 os.chdir(old_path)
441 support.unlink(ABSTFN + "/link-y")
442 safe_rmdir(ABSTFN + "/k/y")
443 safe_rmdir(ABSTFN + "/k")
444 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000445
Brian Curtin52173d42010-12-02 18:29:18 +0000446 @unittest.skipUnless(hasattr(os, "symlink"),
447 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000448 @skip_if_ABSTFN_contains_backslash
449 def test_realpath_resolve_first(self):
450 # Bug #1213894: The first component of the path, if not absolute,
451 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000452
Brian Curtind40e6f72010-07-08 21:39:08 +0000453 try:
454 old_path = abspath('.')
455 os.mkdir(ABSTFN)
456 os.mkdir(ABSTFN + "/k")
457 os.symlink(ABSTFN, ABSTFN + "link")
458 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000459
Brian Curtind40e6f72010-07-08 21:39:08 +0000460 base = basename(ABSTFN)
461 self.assertEqual(realpath(base + "link"), ABSTFN)
462 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
463 finally:
464 os.chdir(old_path)
465 support.unlink(ABSTFN + "link")
466 safe_rmdir(ABSTFN + "/k")
467 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000468
Guido van Rossumd8faa362007-04-27 19:54:29 +0000469 def test_relpath(self):
470 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
471 try:
472 curdir = os.path.split(os.getcwd())[-1]
473 self.assertRaises(ValueError, posixpath.relpath, "")
474 self.assertEqual(posixpath.relpath("a"), "a")
475 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
476 self.assertEqual(posixpath.relpath("a/b"), "a/b")
477 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
478 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000479 self.assertEqual(posixpath.relpath("a/b", "../c"),
480 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000481 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000482 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000483 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
484 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
485 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
486 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
487 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
488 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
489 self.assertEqual(posixpath.relpath("/", "/"), '.')
490 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
491 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000492 finally:
493 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000494
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000495 def test_relpath_bytes(self):
496 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
497 try:
498 curdir = os.path.split(os.getcwdb())[-1]
499 self.assertRaises(ValueError, posixpath.relpath, b"")
500 self.assertEqual(posixpath.relpath(b"a"), b"a")
501 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
502 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
503 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
504 self.assertEqual(posixpath.relpath(b"a", b"../b"),
505 b"../"+curdir+b"/a")
506 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
507 b"../"+curdir+b"/a/b")
508 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
509 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000510 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
511 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
512 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
513 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
514 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
515 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
516 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
517 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
518 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000519
520 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
521 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
522 finally:
523 os.getcwdb = real_getcwdb
524
Florent Xiclunac9c79782010-03-08 12:24:53 +0000525
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200526class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000527 pathmodule = posixpath
528 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
529
530
Brett Cannonb47243a2003-06-16 21:54:50 +0000531if __name__=="__main__":
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200532 unittest.main()