blob: a7a3e4aa12d0ead217e7f3fdbc23724cdf39c78a [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("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200301 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400302 # expanduser should fall back to using the password database
303 del env['HOME']
304 home = pwd.getpwuid(os.getuid()).pw_dir
305 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000306
Brett Cannonb47243a2003-06-16 21:54:50 +0000307 def test_normpath(self):
308 self.assertEqual(posixpath.normpath(""), ".")
309 self.assertEqual(posixpath.normpath("/"), "/")
310 self.assertEqual(posixpath.normpath("//"), "//")
311 self.assertEqual(posixpath.normpath("///"), "/")
312 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000313 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
314 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000315 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
316
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000317 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"///"), b"/")
321 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
322 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
323 b"/foo/baz")
324 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
325 b"/foo/bar")
326
Brian Curtin52173d42010-12-02 18:29:18 +0000327 @unittest.skipUnless(hasattr(os, "symlink"),
328 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000329 @skip_if_ABSTFN_contains_backslash
330 def test_realpath_basic(self):
331 # Basic operation.
332 try:
333 os.symlink(ABSTFN+"1", ABSTFN)
334 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
335 finally:
336 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000337
Brian Curtin52173d42010-12-02 18:29:18 +0000338 @unittest.skipUnless(hasattr(os, "symlink"),
339 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000340 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400341 def test_realpath_relative(self):
342 try:
343 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
344 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
345 finally:
346 support.unlink(ABSTFN)
347
348 @unittest.skipUnless(hasattr(os, "symlink"),
349 "Missing symlink implementation")
350 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000351 def test_realpath_symlink_loops(self):
352 # Bug #930024, return the path unchanged if we get into an infinite
353 # symlink loop.
354 try:
355 old_path = abspath('.')
356 os.symlink(ABSTFN, ABSTFN)
357 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000358
Brian Curtind40e6f72010-07-08 21:39:08 +0000359 os.symlink(ABSTFN+"1", ABSTFN+"2")
360 os.symlink(ABSTFN+"2", ABSTFN+"1")
361 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
362 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000363
Brian Curtind40e6f72010-07-08 21:39:08 +0000364 # Test using relative path as well.
365 os.chdir(dirname(ABSTFN))
366 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
367 finally:
368 os.chdir(old_path)
369 support.unlink(ABSTFN)
370 support.unlink(ABSTFN+"1")
371 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000372
Brian Curtin52173d42010-12-02 18:29:18 +0000373 @unittest.skipUnless(hasattr(os, "symlink"),
374 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000375 @skip_if_ABSTFN_contains_backslash
376 def test_realpath_resolve_parents(self):
377 # We also need to resolve any symlinks in the parents of a relative
378 # path passed to realpath. E.g.: current working directory is
379 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
380 # realpath("a"). This should return /usr/share/doc/a/.
381 try:
382 old_path = abspath('.')
383 os.mkdir(ABSTFN)
384 os.mkdir(ABSTFN + "/y")
385 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000386
Brian Curtind40e6f72010-07-08 21:39:08 +0000387 os.chdir(ABSTFN + "/k")
388 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
389 finally:
390 os.chdir(old_path)
391 support.unlink(ABSTFN + "/k")
392 safe_rmdir(ABSTFN + "/y")
393 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000394
Brian Curtin52173d42010-12-02 18:29:18 +0000395 @unittest.skipUnless(hasattr(os, "symlink"),
396 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000397 @skip_if_ABSTFN_contains_backslash
398 def test_realpath_resolve_before_normalizing(self):
399 # Bug #990669: Symbolic links should be resolved before we
400 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
401 # in the following hierarchy:
402 # a/k/y
403 #
404 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
405 # then realpath("link-y/..") should return 'k', not 'a'.
406 try:
407 old_path = abspath('.')
408 os.mkdir(ABSTFN)
409 os.mkdir(ABSTFN + "/k")
410 os.mkdir(ABSTFN + "/k/y")
411 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000412
Brian Curtind40e6f72010-07-08 21:39:08 +0000413 # Absolute path.
414 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
415 # Relative path.
416 os.chdir(dirname(ABSTFN))
417 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
418 ABSTFN + "/k")
419 finally:
420 os.chdir(old_path)
421 support.unlink(ABSTFN + "/link-y")
422 safe_rmdir(ABSTFN + "/k/y")
423 safe_rmdir(ABSTFN + "/k")
424 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000425
Brian Curtin52173d42010-12-02 18:29:18 +0000426 @unittest.skipUnless(hasattr(os, "symlink"),
427 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000428 @skip_if_ABSTFN_contains_backslash
429 def test_realpath_resolve_first(self):
430 # Bug #1213894: The first component of the path, if not absolute,
431 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000432
Brian Curtind40e6f72010-07-08 21:39:08 +0000433 try:
434 old_path = abspath('.')
435 os.mkdir(ABSTFN)
436 os.mkdir(ABSTFN + "/k")
437 os.symlink(ABSTFN, ABSTFN + "link")
438 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000439
Brian Curtind40e6f72010-07-08 21:39:08 +0000440 base = basename(ABSTFN)
441 self.assertEqual(realpath(base + "link"), ABSTFN)
442 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
443 finally:
444 os.chdir(old_path)
445 support.unlink(ABSTFN + "link")
446 safe_rmdir(ABSTFN + "/k")
447 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000448
Guido van Rossumd8faa362007-04-27 19:54:29 +0000449 def test_relpath(self):
450 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
451 try:
452 curdir = os.path.split(os.getcwd())[-1]
453 self.assertRaises(ValueError, posixpath.relpath, "")
454 self.assertEqual(posixpath.relpath("a"), "a")
455 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
456 self.assertEqual(posixpath.relpath("a/b"), "a/b")
457 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
458 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000459 self.assertEqual(posixpath.relpath("a/b", "../c"),
460 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000461 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000462 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000463 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
464 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
465 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
466 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
467 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
468 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
469 self.assertEqual(posixpath.relpath("/", "/"), '.')
470 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
471 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000472 finally:
473 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000474
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000475 def test_relpath_bytes(self):
476 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
477 try:
478 curdir = os.path.split(os.getcwdb())[-1]
479 self.assertRaises(ValueError, posixpath.relpath, b"")
480 self.assertEqual(posixpath.relpath(b"a"), b"a")
481 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
482 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
483 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
484 self.assertEqual(posixpath.relpath(b"a", b"../b"),
485 b"../"+curdir+b"/a")
486 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
487 b"../"+curdir+b"/a/b")
488 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
489 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000490 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
491 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
492 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
493 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
494 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
495 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
496 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
497 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
498 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000499
500 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
501 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
502 finally:
503 os.getcwdb = real_getcwdb
504
Michael Foord07926f02011-03-16 17:19:16 -0400505 def test_sameopenfile(self):
506 fname = support.TESTFN + "1"
507 with open(fname, "wb") as a, open(fname, "wb") as b:
508 self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno()))
509
Florent Xiclunac9c79782010-03-08 12:24:53 +0000510
511class PosixCommonTest(test_genericpath.CommonTest):
512 pathmodule = posixpath
513 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
514
515
Brett Cannonb47243a2003-06-16 21:54:50 +0000516def test_main():
Florent Xiclunac9c79782010-03-08 12:24:53 +0000517 support.run_unittest(PosixPathTest, PosixCommonTest)
518
Brett Cannonb47243a2003-06-16 21:54:50 +0000519
520if __name__=="__main__":
521 test_main()