blob: bb4559c4abd43bb2a3441ef8dd6a5bd04dcb481e [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
Guido van Rossumf0af3e32008-10-02 18:55:37 +000059 self.assertRaises(TypeError, posixpath.join, b"bytes", "str")
60 self.assertRaises(TypeError, posixpath.join, "str", b"bytes")
Skip Montanaroe809b002000-07-12 00:20:08 +000061
Brett Cannonb47243a2003-06-16 21:54:50 +000062 def test_split(self):
63 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
64 self.assertEqual(posixpath.split("/"), ("/", ""))
65 self.assertEqual(posixpath.split("foo"), ("", "foo"))
66 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
67 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
68
Guido van Rossumf0af3e32008-10-02 18:55:37 +000069 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
70 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
71 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
72 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
73 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
74
Guido van Rossumd8faa362007-04-27 19:54:29 +000075 def splitextTest(self, path, filename, ext):
76 self.assertEqual(posixpath.splitext(path), (filename, ext))
77 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000078 self.assertEqual(posixpath.splitext("abc/" + path),
79 ("abc/" + filename, ext))
80 self.assertEqual(posixpath.splitext("abc.def/" + path),
81 ("abc.def/" + filename, ext))
82 self.assertEqual(posixpath.splitext("/abc.def/" + path),
83 ("/abc.def/" + filename, ext))
84 self.assertEqual(posixpath.splitext(path + "/"),
85 (filename + ext + "/", ""))
86
87 path = bytes(path, "ASCII")
88 filename = bytes(filename, "ASCII")
89 ext = bytes(ext, "ASCII")
90
91 self.assertEqual(posixpath.splitext(path), (filename, ext))
92 self.assertEqual(posixpath.splitext(b"/" + path),
93 (b"/" + filename, ext))
94 self.assertEqual(posixpath.splitext(b"abc/" + path),
95 (b"abc/" + filename, ext))
96 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
97 (b"abc.def/" + filename, ext))
98 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
99 (b"/abc.def/" + filename, ext))
100 self.assertEqual(posixpath.splitext(path + b"/"),
101 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +0000102
Guido van Rossumd8faa362007-04-27 19:54:29 +0000103 def test_splitext(self):
104 self.splitextTest("foo.bar", "foo", ".bar")
105 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
106 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
107 self.splitextTest(".csh.rc", ".csh", ".rc")
108 self.splitextTest("nodots", "nodots", "")
109 self.splitextTest(".cshrc", ".cshrc", "")
110 self.splitextTest("...manydots", "...manydots", "")
111 self.splitextTest("...manydots.ext", "...manydots", ".ext")
112 self.splitextTest(".", ".", "")
113 self.splitextTest("..", "..", "")
114 self.splitextTest("........", "........", "")
115 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000116
117 def test_isabs(self):
118 self.assertIs(posixpath.isabs(""), False)
119 self.assertIs(posixpath.isabs("/"), True)
120 self.assertIs(posixpath.isabs("/foo"), True)
121 self.assertIs(posixpath.isabs("/foo/bar"), True)
122 self.assertIs(posixpath.isabs("foo/bar"), False)
123
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000124 self.assertIs(posixpath.isabs(b""), False)
125 self.assertIs(posixpath.isabs(b"/"), True)
126 self.assertIs(posixpath.isabs(b"/foo"), True)
127 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
128 self.assertIs(posixpath.isabs(b"foo/bar"), False)
129
Brett Cannonb47243a2003-06-16 21:54:50 +0000130 def test_basename(self):
131 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
132 self.assertEqual(posixpath.basename("/"), "")
133 self.assertEqual(posixpath.basename("foo"), "foo")
134 self.assertEqual(posixpath.basename("////foo"), "foo")
135 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
136
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000137 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
138 self.assertEqual(posixpath.basename(b"/"), b"")
139 self.assertEqual(posixpath.basename(b"foo"), b"foo")
140 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
141 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
142
Brett Cannonb47243a2003-06-16 21:54:50 +0000143 def test_dirname(self):
144 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
145 self.assertEqual(posixpath.dirname("/"), "/")
146 self.assertEqual(posixpath.dirname("foo"), "")
147 self.assertEqual(posixpath.dirname("////foo"), "////")
148 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
149
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000150 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
151 self.assertEqual(posixpath.dirname(b"/"), b"/")
152 self.assertEqual(posixpath.dirname(b"foo"), b"")
153 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
154 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
155
Brett Cannonb47243a2003-06-16 21:54:50 +0000156 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000157 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400158 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000159 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000160 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000161 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000162 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000163 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000164 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000165 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
166 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
167 os.remove(support.TESTFN + "1")
168 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
169 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
170 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000171 finally:
172 if not f.close():
173 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000174
Brian Curtind40e6f72010-07-08 21:39:08 +0000175 @staticmethod
176 def _create_file(filename):
177 with open(filename, 'wb') as f:
178 f.write(b'foo')
179
Guido van Rossumd8faa362007-04-27 19:54:29 +0000180 def test_samefile(self):
Brian Curtind40e6f72010-07-08 21:39:08 +0000181 test_fn = support.TESTFN + "1"
182 self._create_file(test_fn)
183 self.assertTrue(posixpath.samefile(test_fn, test_fn))
184 self.assertRaises(TypeError, posixpath.samefile)
185
186 @unittest.skipIf(
187 sys.platform.startswith('win'),
188 "posixpath.samefile does not work on links in Windows")
Brian Curtin52173d42010-12-02 18:29:18 +0000189 @unittest.skipUnless(hasattr(os, "symlink"),
190 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000191 def test_samefile_on_links(self):
192 test_fn1 = support.TESTFN + "1"
193 test_fn2 = support.TESTFN + "2"
194 self._create_file(test_fn1)
195
196 os.symlink(test_fn1, test_fn2)
197 self.assertTrue(posixpath.samefile(test_fn1, test_fn2))
198 os.remove(test_fn2)
199
200 self._create_file(test_fn2)
201 self.assertFalse(posixpath.samefile(test_fn1, test_fn2))
202
Brett Cannonb47243a2003-06-16 21:54:50 +0000203
Brett Cannonb47243a2003-06-16 21:54:50 +0000204 def test_samestat(self):
Brian Curtind40e6f72010-07-08 21:39:08 +0000205 test_fn = support.TESTFN + "1"
206 self._create_file(test_fn)
207 test_fns = [test_fn]*2
208 stats = map(os.stat, test_fns)
209 self.assertTrue(posixpath.samestat(*stats))
210
211 @unittest.skipIf(
212 sys.platform.startswith('win'),
213 "posixpath.samestat does not work on links in Windows")
Brian Curtin52173d42010-12-02 18:29:18 +0000214 @unittest.skipUnless(hasattr(os, "symlink"),
215 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000216 def test_samestat_on_links(self):
217 test_fn1 = support.TESTFN + "1"
218 test_fn2 = support.TESTFN + "2"
Brian Curtin16633fa2010-07-09 13:54:27 +0000219 self._create_file(test_fn1)
Brian Curtind40e6f72010-07-08 21:39:08 +0000220 test_fns = (test_fn1, test_fn2)
221 os.symlink(*test_fns)
222 stats = map(os.stat, test_fns)
223 self.assertTrue(posixpath.samestat(*stats))
224 os.remove(test_fn2)
225
226 self._create_file(test_fn2)
227 stats = map(os.stat, test_fns)
228 self.assertFalse(posixpath.samestat(*stats))
229
230 self.assertRaises(TypeError, posixpath.samestat)
Brett Cannonb47243a2003-06-16 21:54:50 +0000231
Brett Cannonb47243a2003-06-16 21:54:50 +0000232 def test_ismount(self):
233 self.assertIs(posixpath.ismount("/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400234 self.assertIs(posixpath.ismount(b"/"), True)
235
236 def test_ismount_non_existent(self):
237 # Non-existent mountpoint.
238 self.assertIs(posixpath.ismount(ABSTFN), False)
239 try:
240 os.mkdir(ABSTFN)
241 self.assertIs(posixpath.ismount(ABSTFN), False)
242 finally:
243 safe_rmdir(ABSTFN)
244
245 @unittest.skipUnless(support.can_symlink(),
246 "Test requires symlink support")
247 def test_ismount_symlinks(self):
248 # Symlinks are never mountpoints.
249 try:
250 os.symlink("/", ABSTFN)
251 self.assertIs(posixpath.ismount(ABSTFN), False)
252 finally:
253 os.unlink(ABSTFN)
254
255 @unittest.skipIf(posix is None, "Test requires posix module")
256 def test_ismount_different_device(self):
257 # Simulate the path being on a different device from its parent by
258 # mocking out st_dev.
259 save_lstat = os.lstat
260 def fake_lstat(path):
261 st_ino = 0
262 st_dev = 0
263 if path == ABSTFN:
264 st_dev = 1
265 st_ino = 1
266 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
267 try:
268 os.lstat = fake_lstat
269 self.assertIs(posixpath.ismount(ABSTFN), True)
270 finally:
271 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000272
Brett Cannonb47243a2003-06-16 21:54:50 +0000273 def test_expanduser(self):
274 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000275 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000276 try:
277 import pwd
278 except ImportError:
279 pass
280 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000281 self.assertIsInstance(posixpath.expanduser("~/"), str)
282 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000283 # if home directory == root directory, this test makes no sense
284 if posixpath.expanduser("~") != '/':
285 self.assertEqual(
286 posixpath.expanduser("~") + "/",
287 posixpath.expanduser("~/")
288 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000289 self.assertEqual(
290 posixpath.expanduser(b"~") + b"/",
291 posixpath.expanduser(b"~/")
292 )
Ezio Melottie9615932010-01-24 19:26:24 +0000293 self.assertIsInstance(posixpath.expanduser("~root/"), str)
294 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
295 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
296 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000297
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000298 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000299 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000300 self.assertEqual(posixpath.expanduser("~"), "/")
Michael Foord07926f02011-03-16 17:19:16 -0400301 # expanduser should fall back to using the password database
302 del env['HOME']
303 home = pwd.getpwuid(os.getuid()).pw_dir
304 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000305
Brett Cannonb47243a2003-06-16 21:54:50 +0000306 def test_normpath(self):
307 self.assertEqual(posixpath.normpath(""), ".")
308 self.assertEqual(posixpath.normpath("/"), "/")
309 self.assertEqual(posixpath.normpath("//"), "//")
310 self.assertEqual(posixpath.normpath("///"), "/")
311 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000312 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
313 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000314 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
315
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000316 self.assertEqual(posixpath.normpath(b""), b".")
317 self.assertEqual(posixpath.normpath(b"/"), b"/")
318 self.assertEqual(posixpath.normpath(b"//"), b"//")
319 self.assertEqual(posixpath.normpath(b"///"), b"/")
320 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
321 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
322 b"/foo/baz")
323 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
324 b"/foo/bar")
325
Brian Curtin52173d42010-12-02 18:29:18 +0000326 @unittest.skipUnless(hasattr(os, "symlink"),
327 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000328 @skip_if_ABSTFN_contains_backslash
329 def test_realpath_basic(self):
330 # Basic operation.
331 try:
332 os.symlink(ABSTFN+"1", ABSTFN)
333 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
334 finally:
335 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000336
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
Michael Foord07926f02011-03-16 17:19:16 -0400340 def test_realpath_relative(self):
341 try:
342 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
343 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
344 finally:
345 support.unlink(ABSTFN)
346
347 @unittest.skipUnless(hasattr(os, "symlink"),
348 "Missing symlink implementation")
349 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000350 def test_realpath_symlink_loops(self):
351 # Bug #930024, return the path unchanged if we get into an infinite
352 # symlink loop.
353 try:
354 old_path = abspath('.')
355 os.symlink(ABSTFN, ABSTFN)
356 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000357
Brian Curtind40e6f72010-07-08 21:39:08 +0000358 os.symlink(ABSTFN+"1", ABSTFN+"2")
359 os.symlink(ABSTFN+"2", ABSTFN+"1")
360 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
361 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000362
Brian Curtind40e6f72010-07-08 21:39:08 +0000363 # Test using relative path as well.
364 os.chdir(dirname(ABSTFN))
365 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
366 finally:
367 os.chdir(old_path)
368 support.unlink(ABSTFN)
369 support.unlink(ABSTFN+"1")
370 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000371
Brian Curtin52173d42010-12-02 18:29:18 +0000372 @unittest.skipUnless(hasattr(os, "symlink"),
373 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000374 @skip_if_ABSTFN_contains_backslash
375 def test_realpath_resolve_parents(self):
376 # We also need to resolve any symlinks in the parents of a relative
377 # path passed to realpath. E.g.: current working directory is
378 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
379 # realpath("a"). This should return /usr/share/doc/a/.
380 try:
381 old_path = abspath('.')
382 os.mkdir(ABSTFN)
383 os.mkdir(ABSTFN + "/y")
384 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000385
Brian Curtind40e6f72010-07-08 21:39:08 +0000386 os.chdir(ABSTFN + "/k")
387 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
388 finally:
389 os.chdir(old_path)
390 support.unlink(ABSTFN + "/k")
391 safe_rmdir(ABSTFN + "/y")
392 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000393
Brian Curtin52173d42010-12-02 18:29:18 +0000394 @unittest.skipUnless(hasattr(os, "symlink"),
395 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000396 @skip_if_ABSTFN_contains_backslash
397 def test_realpath_resolve_before_normalizing(self):
398 # Bug #990669: Symbolic links should be resolved before we
399 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
400 # in the following hierarchy:
401 # a/k/y
402 #
403 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
404 # then realpath("link-y/..") should return 'k', not 'a'.
405 try:
406 old_path = abspath('.')
407 os.mkdir(ABSTFN)
408 os.mkdir(ABSTFN + "/k")
409 os.mkdir(ABSTFN + "/k/y")
410 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000411
Brian Curtind40e6f72010-07-08 21:39:08 +0000412 # Absolute path.
413 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
414 # Relative path.
415 os.chdir(dirname(ABSTFN))
416 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
417 ABSTFN + "/k")
418 finally:
419 os.chdir(old_path)
420 support.unlink(ABSTFN + "/link-y")
421 safe_rmdir(ABSTFN + "/k/y")
422 safe_rmdir(ABSTFN + "/k")
423 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000424
Brian Curtin52173d42010-12-02 18:29:18 +0000425 @unittest.skipUnless(hasattr(os, "symlink"),
426 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000427 @skip_if_ABSTFN_contains_backslash
428 def test_realpath_resolve_first(self):
429 # Bug #1213894: The first component of the path, if not absolute,
430 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000431
Brian Curtind40e6f72010-07-08 21:39:08 +0000432 try:
433 old_path = abspath('.')
434 os.mkdir(ABSTFN)
435 os.mkdir(ABSTFN + "/k")
436 os.symlink(ABSTFN, ABSTFN + "link")
437 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000438
Brian Curtind40e6f72010-07-08 21:39:08 +0000439 base = basename(ABSTFN)
440 self.assertEqual(realpath(base + "link"), ABSTFN)
441 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
442 finally:
443 os.chdir(old_path)
444 support.unlink(ABSTFN + "link")
445 safe_rmdir(ABSTFN + "/k")
446 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000447
Guido van Rossumd8faa362007-04-27 19:54:29 +0000448 def test_relpath(self):
449 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
450 try:
451 curdir = os.path.split(os.getcwd())[-1]
452 self.assertRaises(ValueError, posixpath.relpath, "")
453 self.assertEqual(posixpath.relpath("a"), "a")
454 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
455 self.assertEqual(posixpath.relpath("a/b"), "a/b")
456 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
457 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000458 self.assertEqual(posixpath.relpath("a/b", "../c"),
459 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000460 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000461 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000462 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
463 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
464 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
465 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
466 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
467 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
468 self.assertEqual(posixpath.relpath("/", "/"), '.')
469 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
470 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000471 finally:
472 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000473
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000474 def test_relpath_bytes(self):
475 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
476 try:
477 curdir = os.path.split(os.getcwdb())[-1]
478 self.assertRaises(ValueError, posixpath.relpath, b"")
479 self.assertEqual(posixpath.relpath(b"a"), b"a")
480 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
481 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
482 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
483 self.assertEqual(posixpath.relpath(b"a", b"../b"),
484 b"../"+curdir+b"/a")
485 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
486 b"../"+curdir+b"/a/b")
487 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
488 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000489 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
490 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
491 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
492 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
493 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
494 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
495 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
496 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
497 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000498
499 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
500 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
501 finally:
502 os.getcwdb = real_getcwdb
503
Michael Foord07926f02011-03-16 17:19:16 -0400504 def test_sameopenfile(self):
505 fname = support.TESTFN + "1"
506 with open(fname, "wb") as a, open(fname, "wb") as b:
507 self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno()))
508
Florent Xiclunac9c79782010-03-08 12:24:53 +0000509
510class PosixCommonTest(test_genericpath.CommonTest):
511 pathmodule = posixpath
512 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
513
514
Brett Cannonb47243a2003-06-16 21:54:50 +0000515def test_main():
Florent Xiclunac9c79782010-03-08 12:24:53 +0000516 support.run_unittest(PosixPathTest, PosixCommonTest)
517
Brett Cannonb47243a2003-06-16 21:54:50 +0000518
519if __name__=="__main__":
520 test_main()