blob: 1ec4a154d997a4377eab6704588c38ac283ec731 [file] [log] [blame]
Brett Cannonb47243a2003-06-16 21:54:50 +00001import unittest
Florent Xiclunac9c79782010-03-08 12:24:53 +00002from test import support, test_genericpath
Skip Montanaroe809b002000-07-12 00:20:08 +00003
Brian Curtind40e6f72010-07-08 21:39:08 +00004import posixpath
5import os
6import sys
Georg Brandl89fad142010-03-14 10:23:39 +00007from posixpath import realpath, abspath, dirname, basename
Johannes Gijsbers4ec40642004-08-14 15:01:53 +00008
Michael Foord07926f02011-03-16 17:19:16 -04009try:
10 import posix
11except ImportError:
12 posix = None
13
Johannes Gijsbers4ec40642004-08-14 15:01:53 +000014# An absolute path to a temporary filename for testing. We can't rely on TESTFN
15# being an absolute path, so we need this.
16
Benjamin Petersonee8712c2008-05-20 21:35:26 +000017ABSTFN = abspath(support.TESTFN)
Skip Montanaroe809b002000-07-12 00:20:08 +000018
Brian Curtind40e6f72010-07-08 21:39:08 +000019def skip_if_ABSTFN_contains_backslash(test):
20 """
21 On Windows, posixpath.abspath still returns paths with backslashes
22 instead of posix forward slashes. If this is the case, several tests
23 fail, so skip them.
24 """
25 found_backslash = '\\' in ABSTFN
26 msg = "ABSTFN is not a posix path - tests fail"
27 return [test, unittest.skip(msg)(test)][found_backslash]
28
Guido van Rossumd8faa362007-04-27 19:54:29 +000029def safe_rmdir(dirname):
30 try:
31 os.rmdir(dirname)
32 except OSError:
33 pass
34
Brett Cannonb47243a2003-06-16 21:54:50 +000035class PosixPathTest(unittest.TestCase):
Skip Montanaroe809b002000-07-12 00:20:08 +000036
Guido van Rossumd8faa362007-04-27 19:54:29 +000037 def setUp(self):
38 self.tearDown()
39
40 def tearDown(self):
41 for suffix in ["", "1", "2"]:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000042 support.unlink(support.TESTFN + suffix)
43 safe_rmdir(support.TESTFN + suffix)
Guido van Rossumd8faa362007-04-27 19:54:29 +000044
Brett Cannonb47243a2003-06-16 21:54:50 +000045 def test_join(self):
Guido van Rossumf0af3e32008-10-02 18:55:37 +000046 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"),
47 "/bar/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +000048 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
Guido van Rossumf0af3e32008-10-02 18:55:37 +000049 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"),
50 "/foo/bar/baz/")
51
52 self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"),
53 b"/bar/baz")
54 self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"),
55 b"/foo/bar/baz")
56 self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"),
57 b"/foo/bar/baz/")
Skip Montanaroe809b002000-07-12 00:20:08 +000058
Hynek Schlawack7cdc2bd2012-07-17 10:48:19 +020059 # Check for friendly str/bytes mixing message
60 for args in [[b'bytes', 'str'],
61 [bytearray(b'bytes'), 'str']]:
62 for _ in range(2):
63 with self.assertRaises(TypeError) as cm:
64 posixpath.join(*args)
65 self.assertEqual(
66 "Can't mix strings and bytes in path components.",
67 cm.exception.args[0]
68 )
69 args.reverse() # check both orders
70
Skip Montanaroe809b002000-07-12 00:20:08 +000071
Brett Cannonb47243a2003-06-16 21:54:50 +000072 def test_split(self):
73 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
74 self.assertEqual(posixpath.split("/"), ("/", ""))
75 self.assertEqual(posixpath.split("foo"), ("", "foo"))
76 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
77 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
78
Guido van Rossumf0af3e32008-10-02 18:55:37 +000079 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
80 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
81 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
82 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
83 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
84
Guido van Rossumd8faa362007-04-27 19:54:29 +000085 def splitextTest(self, path, filename, ext):
86 self.assertEqual(posixpath.splitext(path), (filename, ext))
87 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000088 self.assertEqual(posixpath.splitext("abc/" + path),
89 ("abc/" + filename, ext))
90 self.assertEqual(posixpath.splitext("abc.def/" + path),
91 ("abc.def/" + filename, ext))
92 self.assertEqual(posixpath.splitext("/abc.def/" + path),
93 ("/abc.def/" + filename, ext))
94 self.assertEqual(posixpath.splitext(path + "/"),
95 (filename + ext + "/", ""))
96
97 path = bytes(path, "ASCII")
98 filename = bytes(filename, "ASCII")
99 ext = bytes(ext, "ASCII")
100
101 self.assertEqual(posixpath.splitext(path), (filename, ext))
102 self.assertEqual(posixpath.splitext(b"/" + path),
103 (b"/" + filename, ext))
104 self.assertEqual(posixpath.splitext(b"abc/" + path),
105 (b"abc/" + filename, ext))
106 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
107 (b"abc.def/" + filename, ext))
108 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
109 (b"/abc.def/" + filename, ext))
110 self.assertEqual(posixpath.splitext(path + b"/"),
111 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +0000112
Guido van Rossumd8faa362007-04-27 19:54:29 +0000113 def test_splitext(self):
114 self.splitextTest("foo.bar", "foo", ".bar")
115 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
116 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
117 self.splitextTest(".csh.rc", ".csh", ".rc")
118 self.splitextTest("nodots", "nodots", "")
119 self.splitextTest(".cshrc", ".cshrc", "")
120 self.splitextTest("...manydots", "...manydots", "")
121 self.splitextTest("...manydots.ext", "...manydots", ".ext")
122 self.splitextTest(".", ".", "")
123 self.splitextTest("..", "..", "")
124 self.splitextTest("........", "........", "")
125 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000126
127 def test_isabs(self):
128 self.assertIs(posixpath.isabs(""), False)
129 self.assertIs(posixpath.isabs("/"), True)
130 self.assertIs(posixpath.isabs("/foo"), True)
131 self.assertIs(posixpath.isabs("/foo/bar"), True)
132 self.assertIs(posixpath.isabs("foo/bar"), False)
133
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000134 self.assertIs(posixpath.isabs(b""), False)
135 self.assertIs(posixpath.isabs(b"/"), True)
136 self.assertIs(posixpath.isabs(b"/foo"), True)
137 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
138 self.assertIs(posixpath.isabs(b"foo/bar"), False)
139
Brett Cannonb47243a2003-06-16 21:54:50 +0000140 def test_basename(self):
141 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
142 self.assertEqual(posixpath.basename("/"), "")
143 self.assertEqual(posixpath.basename("foo"), "foo")
144 self.assertEqual(posixpath.basename("////foo"), "foo")
145 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
146
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000147 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
148 self.assertEqual(posixpath.basename(b"/"), b"")
149 self.assertEqual(posixpath.basename(b"foo"), b"foo")
150 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
151 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
152
Brett Cannonb47243a2003-06-16 21:54:50 +0000153 def test_dirname(self):
154 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
155 self.assertEqual(posixpath.dirname("/"), "/")
156 self.assertEqual(posixpath.dirname("foo"), "")
157 self.assertEqual(posixpath.dirname("////foo"), "////")
158 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
159
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000160 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
161 self.assertEqual(posixpath.dirname(b"/"), b"/")
162 self.assertEqual(posixpath.dirname(b"foo"), b"")
163 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
164 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
165
Brett Cannonb47243a2003-06-16 21:54:50 +0000166 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000167 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400168 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000169 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000170 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000171 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000172 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000173 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000174 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000175 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
176 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
177 os.remove(support.TESTFN + "1")
178 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
179 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
180 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000181 finally:
182 if not f.close():
183 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000184
Brian Curtind40e6f72010-07-08 21:39:08 +0000185 @staticmethod
186 def _create_file(filename):
187 with open(filename, 'wb') as f:
188 f.write(b'foo')
189
Guido van Rossumd8faa362007-04-27 19:54:29 +0000190 def test_samefile(self):
Brian Curtind40e6f72010-07-08 21:39:08 +0000191 test_fn = support.TESTFN + "1"
192 self._create_file(test_fn)
193 self.assertTrue(posixpath.samefile(test_fn, test_fn))
194 self.assertRaises(TypeError, posixpath.samefile)
195
196 @unittest.skipIf(
197 sys.platform.startswith('win'),
198 "posixpath.samefile does not work on links in Windows")
Brian Curtin52173d42010-12-02 18:29:18 +0000199 @unittest.skipUnless(hasattr(os, "symlink"),
200 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000201 def test_samefile_on_links(self):
202 test_fn1 = support.TESTFN + "1"
203 test_fn2 = support.TESTFN + "2"
204 self._create_file(test_fn1)
205
206 os.symlink(test_fn1, test_fn2)
207 self.assertTrue(posixpath.samefile(test_fn1, test_fn2))
208 os.remove(test_fn2)
209
210 self._create_file(test_fn2)
211 self.assertFalse(posixpath.samefile(test_fn1, test_fn2))
212
Brett Cannonb47243a2003-06-16 21:54:50 +0000213
Brett Cannonb47243a2003-06-16 21:54:50 +0000214 def test_samestat(self):
Brian Curtind40e6f72010-07-08 21:39:08 +0000215 test_fn = support.TESTFN + "1"
216 self._create_file(test_fn)
217 test_fns = [test_fn]*2
218 stats = map(os.stat, test_fns)
219 self.assertTrue(posixpath.samestat(*stats))
220
221 @unittest.skipIf(
222 sys.platform.startswith('win'),
223 "posixpath.samestat does not work on links in Windows")
Brian Curtin52173d42010-12-02 18:29:18 +0000224 @unittest.skipUnless(hasattr(os, "symlink"),
225 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000226 def test_samestat_on_links(self):
227 test_fn1 = support.TESTFN + "1"
228 test_fn2 = support.TESTFN + "2"
Brian Curtin16633fa2010-07-09 13:54:27 +0000229 self._create_file(test_fn1)
Brian Curtind40e6f72010-07-08 21:39:08 +0000230 test_fns = (test_fn1, test_fn2)
231 os.symlink(*test_fns)
232 stats = map(os.stat, test_fns)
233 self.assertTrue(posixpath.samestat(*stats))
234 os.remove(test_fn2)
235
236 self._create_file(test_fn2)
237 stats = map(os.stat, test_fns)
238 self.assertFalse(posixpath.samestat(*stats))
239
240 self.assertRaises(TypeError, posixpath.samestat)
Brett Cannonb47243a2003-06-16 21:54:50 +0000241
Brett Cannonb47243a2003-06-16 21:54:50 +0000242 def test_ismount(self):
243 self.assertIs(posixpath.ismount("/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400244 self.assertIs(posixpath.ismount(b"/"), True)
245
246 def test_ismount_non_existent(self):
247 # Non-existent mountpoint.
248 self.assertIs(posixpath.ismount(ABSTFN), False)
249 try:
250 os.mkdir(ABSTFN)
251 self.assertIs(posixpath.ismount(ABSTFN), False)
252 finally:
253 safe_rmdir(ABSTFN)
254
255 @unittest.skipUnless(support.can_symlink(),
256 "Test requires symlink support")
257 def test_ismount_symlinks(self):
258 # Symlinks are never mountpoints.
259 try:
260 os.symlink("/", ABSTFN)
261 self.assertIs(posixpath.ismount(ABSTFN), False)
262 finally:
263 os.unlink(ABSTFN)
264
265 @unittest.skipIf(posix is None, "Test requires posix module")
266 def test_ismount_different_device(self):
267 # Simulate the path being on a different device from its parent by
268 # mocking out st_dev.
269 save_lstat = os.lstat
270 def fake_lstat(path):
271 st_ino = 0
272 st_dev = 0
273 if path == ABSTFN:
274 st_dev = 1
275 st_ino = 1
276 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
277 try:
278 os.lstat = fake_lstat
279 self.assertIs(posixpath.ismount(ABSTFN), True)
280 finally:
281 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000282
Brett Cannonb47243a2003-06-16 21:54:50 +0000283 def test_expanduser(self):
284 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000285 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000286 try:
287 import pwd
288 except ImportError:
289 pass
290 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000291 self.assertIsInstance(posixpath.expanduser("~/"), str)
292 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000293 # if home directory == root directory, this test makes no sense
294 if posixpath.expanduser("~") != '/':
295 self.assertEqual(
296 posixpath.expanduser("~") + "/",
297 posixpath.expanduser("~/")
298 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000299 self.assertEqual(
300 posixpath.expanduser(b"~") + b"/",
301 posixpath.expanduser(b"~/")
302 )
Ezio Melottie9615932010-01-24 19:26:24 +0000303 self.assertIsInstance(posixpath.expanduser("~root/"), str)
304 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
305 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
306 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000307
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000308 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000309 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000310 self.assertEqual(posixpath.expanduser("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200311 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400312 # expanduser should fall back to using the password database
313 del env['HOME']
314 home = pwd.getpwuid(os.getuid()).pw_dir
315 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000316
Brett Cannonb47243a2003-06-16 21:54:50 +0000317 def test_normpath(self):
318 self.assertEqual(posixpath.normpath(""), ".")
319 self.assertEqual(posixpath.normpath("/"), "/")
320 self.assertEqual(posixpath.normpath("//"), "//")
321 self.assertEqual(posixpath.normpath("///"), "/")
322 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000323 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
324 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000325 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
326
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000327 self.assertEqual(posixpath.normpath(b""), b".")
328 self.assertEqual(posixpath.normpath(b"/"), b"/")
329 self.assertEqual(posixpath.normpath(b"//"), b"//")
330 self.assertEqual(posixpath.normpath(b"///"), b"/")
331 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
332 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
333 b"/foo/baz")
334 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
335 b"/foo/bar")
336
Brian Curtin52173d42010-12-02 18:29:18 +0000337 @unittest.skipUnless(hasattr(os, "symlink"),
338 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000339 @skip_if_ABSTFN_contains_backslash
340 def test_realpath_basic(self):
341 # Basic operation.
342 try:
343 os.symlink(ABSTFN+"1", ABSTFN)
344 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
345 finally:
346 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000347
Brian Curtin52173d42010-12-02 18:29:18 +0000348 @unittest.skipUnless(hasattr(os, "symlink"),
349 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000350 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400351 def test_realpath_relative(self):
352 try:
353 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
354 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
355 finally:
356 support.unlink(ABSTFN)
357
358 @unittest.skipUnless(hasattr(os, "symlink"),
359 "Missing symlink implementation")
360 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000361 def test_realpath_symlink_loops(self):
362 # Bug #930024, return the path unchanged if we get into an infinite
363 # symlink loop.
364 try:
365 old_path = abspath('.')
366 os.symlink(ABSTFN, ABSTFN)
367 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000368
Brian Curtind40e6f72010-07-08 21:39:08 +0000369 os.symlink(ABSTFN+"1", ABSTFN+"2")
370 os.symlink(ABSTFN+"2", ABSTFN+"1")
371 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
372 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000373
Brian Curtind40e6f72010-07-08 21:39:08 +0000374 # Test using relative path as well.
375 os.chdir(dirname(ABSTFN))
376 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
377 finally:
378 os.chdir(old_path)
379 support.unlink(ABSTFN)
380 support.unlink(ABSTFN+"1")
381 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000382
Brian Curtin52173d42010-12-02 18:29:18 +0000383 @unittest.skipUnless(hasattr(os, "symlink"),
384 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000385 @skip_if_ABSTFN_contains_backslash
386 def test_realpath_resolve_parents(self):
387 # We also need to resolve any symlinks in the parents of a relative
388 # path passed to realpath. E.g.: current working directory is
389 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
390 # realpath("a"). This should return /usr/share/doc/a/.
391 try:
392 old_path = abspath('.')
393 os.mkdir(ABSTFN)
394 os.mkdir(ABSTFN + "/y")
395 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000396
Brian Curtind40e6f72010-07-08 21:39:08 +0000397 os.chdir(ABSTFN + "/k")
398 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
399 finally:
400 os.chdir(old_path)
401 support.unlink(ABSTFN + "/k")
402 safe_rmdir(ABSTFN + "/y")
403 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000404
Brian Curtin52173d42010-12-02 18:29:18 +0000405 @unittest.skipUnless(hasattr(os, "symlink"),
406 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000407 @skip_if_ABSTFN_contains_backslash
408 def test_realpath_resolve_before_normalizing(self):
409 # Bug #990669: Symbolic links should be resolved before we
410 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
411 # in the following hierarchy:
412 # a/k/y
413 #
414 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
415 # then realpath("link-y/..") should return 'k', not 'a'.
416 try:
417 old_path = abspath('.')
418 os.mkdir(ABSTFN)
419 os.mkdir(ABSTFN + "/k")
420 os.mkdir(ABSTFN + "/k/y")
421 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000422
Brian Curtind40e6f72010-07-08 21:39:08 +0000423 # Absolute path.
424 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
425 # Relative path.
426 os.chdir(dirname(ABSTFN))
427 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
428 ABSTFN + "/k")
429 finally:
430 os.chdir(old_path)
431 support.unlink(ABSTFN + "/link-y")
432 safe_rmdir(ABSTFN + "/k/y")
433 safe_rmdir(ABSTFN + "/k")
434 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000435
Brian Curtin52173d42010-12-02 18:29:18 +0000436 @unittest.skipUnless(hasattr(os, "symlink"),
437 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000438 @skip_if_ABSTFN_contains_backslash
439 def test_realpath_resolve_first(self):
440 # Bug #1213894: The first component of the path, if not absolute,
441 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000442
Brian Curtind40e6f72010-07-08 21:39:08 +0000443 try:
444 old_path = abspath('.')
445 os.mkdir(ABSTFN)
446 os.mkdir(ABSTFN + "/k")
447 os.symlink(ABSTFN, ABSTFN + "link")
448 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000449
Brian Curtind40e6f72010-07-08 21:39:08 +0000450 base = basename(ABSTFN)
451 self.assertEqual(realpath(base + "link"), ABSTFN)
452 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
453 finally:
454 os.chdir(old_path)
455 support.unlink(ABSTFN + "link")
456 safe_rmdir(ABSTFN + "/k")
457 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000458
Guido van Rossumd8faa362007-04-27 19:54:29 +0000459 def test_relpath(self):
460 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
461 try:
462 curdir = os.path.split(os.getcwd())[-1]
463 self.assertRaises(ValueError, posixpath.relpath, "")
464 self.assertEqual(posixpath.relpath("a"), "a")
465 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
466 self.assertEqual(posixpath.relpath("a/b"), "a/b")
467 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
468 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000469 self.assertEqual(posixpath.relpath("a/b", "../c"),
470 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000471 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000472 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000473 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
474 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
475 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
476 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
477 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
478 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
479 self.assertEqual(posixpath.relpath("/", "/"), '.')
480 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
481 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000482 finally:
483 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000484
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000485 def test_relpath_bytes(self):
486 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
487 try:
488 curdir = os.path.split(os.getcwdb())[-1]
489 self.assertRaises(ValueError, posixpath.relpath, b"")
490 self.assertEqual(posixpath.relpath(b"a"), b"a")
491 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
492 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
493 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
494 self.assertEqual(posixpath.relpath(b"a", b"../b"),
495 b"../"+curdir+b"/a")
496 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
497 b"../"+curdir+b"/a/b")
498 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
499 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000500 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
501 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
502 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
503 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
504 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
505 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
506 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
507 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
508 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000509
510 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
511 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
512 finally:
513 os.getcwdb = real_getcwdb
514
Michael Foord07926f02011-03-16 17:19:16 -0400515 def test_sameopenfile(self):
516 fname = support.TESTFN + "1"
517 with open(fname, "wb") as a, open(fname, "wb") as b:
518 self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno()))
519
Florent Xiclunac9c79782010-03-08 12:24:53 +0000520
521class PosixCommonTest(test_genericpath.CommonTest):
522 pathmodule = posixpath
523 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
524
525
Brett Cannonb47243a2003-06-16 21:54:50 +0000526def test_main():
Florent Xiclunac9c79782010-03-08 12:24:53 +0000527 support.run_unittest(PosixPathTest, PosixCommonTest)
528
Brett Cannonb47243a2003-06-16 21:54:50 +0000529
530if __name__=="__main__":
531 test_main()