blob: 43442e5acce512f9f9c8a787e2b9e7c530e13805 [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
Brian Curtin52173d42010-12-02 18:29:18 +0000286 @unittest.skipUnless(hasattr(os, "symlink"),
287 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000288 @skip_if_ABSTFN_contains_backslash
289 def test_realpath_basic(self):
290 # Basic operation.
291 try:
292 os.symlink(ABSTFN+"1", ABSTFN)
293 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
294 finally:
295 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000296
Brian Curtin52173d42010-12-02 18:29:18 +0000297 @unittest.skipUnless(hasattr(os, "symlink"),
298 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000299 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400300 def test_realpath_relative(self):
301 try:
302 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
303 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
304 finally:
305 support.unlink(ABSTFN)
306
307 @unittest.skipUnless(hasattr(os, "symlink"),
308 "Missing symlink implementation")
309 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000310 def test_realpath_symlink_loops(self):
311 # Bug #930024, return the path unchanged if we get into an infinite
312 # symlink loop.
313 try:
314 old_path = abspath('.')
315 os.symlink(ABSTFN, ABSTFN)
316 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000317
Brian Curtind40e6f72010-07-08 21:39:08 +0000318 os.symlink(ABSTFN+"1", ABSTFN+"2")
319 os.symlink(ABSTFN+"2", ABSTFN+"1")
320 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
321 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000322
Brian Curtind40e6f72010-07-08 21:39:08 +0000323 # Test using relative path as well.
324 os.chdir(dirname(ABSTFN))
325 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
326 finally:
327 os.chdir(old_path)
328 support.unlink(ABSTFN)
329 support.unlink(ABSTFN+"1")
330 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000331
Brian Curtin52173d42010-12-02 18:29:18 +0000332 @unittest.skipUnless(hasattr(os, "symlink"),
333 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000334 @skip_if_ABSTFN_contains_backslash
335 def test_realpath_resolve_parents(self):
336 # We also need to resolve any symlinks in the parents of a relative
337 # path passed to realpath. E.g.: current working directory is
338 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
339 # realpath("a"). This should return /usr/share/doc/a/.
340 try:
341 old_path = abspath('.')
342 os.mkdir(ABSTFN)
343 os.mkdir(ABSTFN + "/y")
344 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000345
Brian Curtind40e6f72010-07-08 21:39:08 +0000346 os.chdir(ABSTFN + "/k")
347 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
348 finally:
349 os.chdir(old_path)
350 support.unlink(ABSTFN + "/k")
351 safe_rmdir(ABSTFN + "/y")
352 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000353
Brian Curtin52173d42010-12-02 18:29:18 +0000354 @unittest.skipUnless(hasattr(os, "symlink"),
355 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000356 @skip_if_ABSTFN_contains_backslash
357 def test_realpath_resolve_before_normalizing(self):
358 # Bug #990669: Symbolic links should be resolved before we
359 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
360 # in the following hierarchy:
361 # a/k/y
362 #
363 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
364 # then realpath("link-y/..") should return 'k', not 'a'.
365 try:
366 old_path = abspath('.')
367 os.mkdir(ABSTFN)
368 os.mkdir(ABSTFN + "/k")
369 os.mkdir(ABSTFN + "/k/y")
370 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000371
Brian Curtind40e6f72010-07-08 21:39:08 +0000372 # Absolute path.
373 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
374 # Relative path.
375 os.chdir(dirname(ABSTFN))
376 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
377 ABSTFN + "/k")
378 finally:
379 os.chdir(old_path)
380 support.unlink(ABSTFN + "/link-y")
381 safe_rmdir(ABSTFN + "/k/y")
382 safe_rmdir(ABSTFN + "/k")
383 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000384
Brian Curtin52173d42010-12-02 18:29:18 +0000385 @unittest.skipUnless(hasattr(os, "symlink"),
386 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000387 @skip_if_ABSTFN_contains_backslash
388 def test_realpath_resolve_first(self):
389 # Bug #1213894: The first component of the path, if not absolute,
390 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000391
Brian Curtind40e6f72010-07-08 21:39:08 +0000392 try:
393 old_path = abspath('.')
394 os.mkdir(ABSTFN)
395 os.mkdir(ABSTFN + "/k")
396 os.symlink(ABSTFN, ABSTFN + "link")
397 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000398
Brian Curtind40e6f72010-07-08 21:39:08 +0000399 base = basename(ABSTFN)
400 self.assertEqual(realpath(base + "link"), ABSTFN)
401 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
402 finally:
403 os.chdir(old_path)
404 support.unlink(ABSTFN + "link")
405 safe_rmdir(ABSTFN + "/k")
406 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000407
Guido van Rossumd8faa362007-04-27 19:54:29 +0000408 def test_relpath(self):
409 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
410 try:
411 curdir = os.path.split(os.getcwd())[-1]
412 self.assertRaises(ValueError, posixpath.relpath, "")
413 self.assertEqual(posixpath.relpath("a"), "a")
414 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
415 self.assertEqual(posixpath.relpath("a/b"), "a/b")
416 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
417 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000418 self.assertEqual(posixpath.relpath("a/b", "../c"),
419 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000420 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000421 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000422 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
423 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
424 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
425 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
426 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
427 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
428 self.assertEqual(posixpath.relpath("/", "/"), '.')
429 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
430 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000431 finally:
432 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000433
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000434 def test_relpath_bytes(self):
435 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
436 try:
437 curdir = os.path.split(os.getcwdb())[-1]
438 self.assertRaises(ValueError, posixpath.relpath, b"")
439 self.assertEqual(posixpath.relpath(b"a"), b"a")
440 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
441 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
442 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
443 self.assertEqual(posixpath.relpath(b"a", b"../b"),
444 b"../"+curdir+b"/a")
445 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
446 b"../"+curdir+b"/a/b")
447 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
448 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000449 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
450 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
451 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
452 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
453 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
454 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
455 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
456 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
457 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000458
459 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
460 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
461 finally:
462 os.getcwdb = real_getcwdb
463
Florent Xiclunac9c79782010-03-08 12:24:53 +0000464
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200465class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
Florent Xiclunac9c79782010-03-08 12:24:53 +0000466 pathmodule = posixpath
467 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
468
469
Brett Cannonb47243a2003-06-16 21:54:50 +0000470if __name__=="__main__":
Ezio Melottid0dfe9a2013-01-10 03:12:50 +0200471 unittest.main()