blob: 709ef040fad2df2e1465683683dc6e13301bafd9 [file] [log] [blame]
Brian Curtind40e6f72010-07-08 21:39:08 +00001import os
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002import posixpath
Brian Curtind40e6f72010-07-08 21:39:08 +00003import sys
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004import unittest
5import warnings
Georg Brandl89fad142010-03-14 10:23:39 +00006from posixpath import realpath, abspath, dirname, basename
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01007from test import support, test_genericpath
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)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100234 with warnings.catch_warnings():
235 warnings.simplefilter("ignore", DeprecationWarning)
236 self.assertIs(posixpath.ismount(b"/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400237
238 def test_ismount_non_existent(self):
239 # Non-existent mountpoint.
240 self.assertIs(posixpath.ismount(ABSTFN), False)
241 try:
242 os.mkdir(ABSTFN)
243 self.assertIs(posixpath.ismount(ABSTFN), False)
244 finally:
245 safe_rmdir(ABSTFN)
246
247 @unittest.skipUnless(support.can_symlink(),
248 "Test requires symlink support")
249 def test_ismount_symlinks(self):
250 # Symlinks are never mountpoints.
251 try:
252 os.symlink("/", ABSTFN)
253 self.assertIs(posixpath.ismount(ABSTFN), False)
254 finally:
255 os.unlink(ABSTFN)
256
257 @unittest.skipIf(posix is None, "Test requires posix module")
258 def test_ismount_different_device(self):
259 # Simulate the path being on a different device from its parent by
260 # mocking out st_dev.
261 save_lstat = os.lstat
262 def fake_lstat(path):
263 st_ino = 0
264 st_dev = 0
265 if path == ABSTFN:
266 st_dev = 1
267 st_ino = 1
268 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
269 try:
270 os.lstat = fake_lstat
271 self.assertIs(posixpath.ismount(ABSTFN), True)
272 finally:
273 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000274
Brett Cannonb47243a2003-06-16 21:54:50 +0000275 def test_expanduser(self):
276 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000277 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000278 try:
279 import pwd
280 except ImportError:
281 pass
282 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000283 self.assertIsInstance(posixpath.expanduser("~/"), str)
284 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000285 # if home directory == root directory, this test makes no sense
286 if posixpath.expanduser("~") != '/':
287 self.assertEqual(
288 posixpath.expanduser("~") + "/",
289 posixpath.expanduser("~/")
290 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000291 self.assertEqual(
292 posixpath.expanduser(b"~") + b"/",
293 posixpath.expanduser(b"~/")
294 )
Ezio Melottie9615932010-01-24 19:26:24 +0000295 self.assertIsInstance(posixpath.expanduser("~root/"), str)
296 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
297 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
298 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000299
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000300 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000301 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000302 self.assertEqual(posixpath.expanduser("~"), "/")
Michael Foord07926f02011-03-16 17:19:16 -0400303 # expanduser should fall back to using the password database
304 del env['HOME']
305 home = pwd.getpwuid(os.getuid()).pw_dir
306 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000307
Brett Cannonb47243a2003-06-16 21:54:50 +0000308 def test_normpath(self):
309 self.assertEqual(posixpath.normpath(""), ".")
310 self.assertEqual(posixpath.normpath("/"), "/")
311 self.assertEqual(posixpath.normpath("//"), "//")
312 self.assertEqual(posixpath.normpath("///"), "/")
313 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000314 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
315 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000316 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
317
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000318 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"///"), b"/")
322 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
323 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
324 b"/foo/baz")
325 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
326 b"/foo/bar")
327
Brian Curtin52173d42010-12-02 18:29:18 +0000328 @unittest.skipUnless(hasattr(os, "symlink"),
329 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000330 @skip_if_ABSTFN_contains_backslash
331 def test_realpath_basic(self):
332 # Basic operation.
333 try:
334 os.symlink(ABSTFN+"1", ABSTFN)
335 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
336 finally:
337 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000338
Brian Curtin52173d42010-12-02 18:29:18 +0000339 @unittest.skipUnless(hasattr(os, "symlink"),
340 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000341 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400342 def test_realpath_relative(self):
343 try:
344 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
345 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
346 finally:
347 support.unlink(ABSTFN)
348
349 @unittest.skipUnless(hasattr(os, "symlink"),
350 "Missing symlink implementation")
351 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000352 def test_realpath_symlink_loops(self):
353 # Bug #930024, return the path unchanged if we get into an infinite
354 # symlink loop.
355 try:
356 old_path = abspath('.')
357 os.symlink(ABSTFN, ABSTFN)
358 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000359
Brian Curtind40e6f72010-07-08 21:39:08 +0000360 os.symlink(ABSTFN+"1", ABSTFN+"2")
361 os.symlink(ABSTFN+"2", ABSTFN+"1")
362 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
363 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000364
Brian Curtind40e6f72010-07-08 21:39:08 +0000365 # Test using relative path as well.
366 os.chdir(dirname(ABSTFN))
367 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
368 finally:
369 os.chdir(old_path)
370 support.unlink(ABSTFN)
371 support.unlink(ABSTFN+"1")
372 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000373
Brian Curtin52173d42010-12-02 18:29:18 +0000374 @unittest.skipUnless(hasattr(os, "symlink"),
375 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000376 @skip_if_ABSTFN_contains_backslash
377 def test_realpath_resolve_parents(self):
378 # We also need to resolve any symlinks in the parents of a relative
379 # path passed to realpath. E.g.: current working directory is
380 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
381 # realpath("a"). This should return /usr/share/doc/a/.
382 try:
383 old_path = abspath('.')
384 os.mkdir(ABSTFN)
385 os.mkdir(ABSTFN + "/y")
386 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000387
Brian Curtind40e6f72010-07-08 21:39:08 +0000388 os.chdir(ABSTFN + "/k")
389 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
390 finally:
391 os.chdir(old_path)
392 support.unlink(ABSTFN + "/k")
393 safe_rmdir(ABSTFN + "/y")
394 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000395
Brian Curtin52173d42010-12-02 18:29:18 +0000396 @unittest.skipUnless(hasattr(os, "symlink"),
397 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000398 @skip_if_ABSTFN_contains_backslash
399 def test_realpath_resolve_before_normalizing(self):
400 # Bug #990669: Symbolic links should be resolved before we
401 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
402 # in the following hierarchy:
403 # a/k/y
404 #
405 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
406 # then realpath("link-y/..") should return 'k', not 'a'.
407 try:
408 old_path = abspath('.')
409 os.mkdir(ABSTFN)
410 os.mkdir(ABSTFN + "/k")
411 os.mkdir(ABSTFN + "/k/y")
412 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000413
Brian Curtind40e6f72010-07-08 21:39:08 +0000414 # Absolute path.
415 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
416 # Relative path.
417 os.chdir(dirname(ABSTFN))
418 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
419 ABSTFN + "/k")
420 finally:
421 os.chdir(old_path)
422 support.unlink(ABSTFN + "/link-y")
423 safe_rmdir(ABSTFN + "/k/y")
424 safe_rmdir(ABSTFN + "/k")
425 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000426
Brian Curtin52173d42010-12-02 18:29:18 +0000427 @unittest.skipUnless(hasattr(os, "symlink"),
428 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000429 @skip_if_ABSTFN_contains_backslash
430 def test_realpath_resolve_first(self):
431 # Bug #1213894: The first component of the path, if not absolute,
432 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000433
Brian Curtind40e6f72010-07-08 21:39:08 +0000434 try:
435 old_path = abspath('.')
436 os.mkdir(ABSTFN)
437 os.mkdir(ABSTFN + "/k")
438 os.symlink(ABSTFN, ABSTFN + "link")
439 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000440
Brian Curtind40e6f72010-07-08 21:39:08 +0000441 base = basename(ABSTFN)
442 self.assertEqual(realpath(base + "link"), ABSTFN)
443 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
444 finally:
445 os.chdir(old_path)
446 support.unlink(ABSTFN + "link")
447 safe_rmdir(ABSTFN + "/k")
448 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000449
Guido van Rossumd8faa362007-04-27 19:54:29 +0000450 def test_relpath(self):
451 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
452 try:
453 curdir = os.path.split(os.getcwd())[-1]
454 self.assertRaises(ValueError, posixpath.relpath, "")
455 self.assertEqual(posixpath.relpath("a"), "a")
456 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
457 self.assertEqual(posixpath.relpath("a/b"), "a/b")
458 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
459 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000460 self.assertEqual(posixpath.relpath("a/b", "../c"),
461 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000462 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000463 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000464 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
465 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
466 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
467 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
468 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
469 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
470 self.assertEqual(posixpath.relpath("/", "/"), '.')
471 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
472 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000473 finally:
474 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000475
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000476 def test_relpath_bytes(self):
477 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
478 try:
479 curdir = os.path.split(os.getcwdb())[-1]
480 self.assertRaises(ValueError, posixpath.relpath, b"")
481 self.assertEqual(posixpath.relpath(b"a"), b"a")
482 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
483 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
484 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
485 self.assertEqual(posixpath.relpath(b"a", b"../b"),
486 b"../"+curdir+b"/a")
487 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
488 b"../"+curdir+b"/a/b")
489 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
490 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000491 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
492 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
493 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
494 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
495 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
496 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
497 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
498 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
499 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000500
501 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
502 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
503 finally:
504 os.getcwdb = real_getcwdb
505
Michael Foord07926f02011-03-16 17:19:16 -0400506 def test_sameopenfile(self):
507 fname = support.TESTFN + "1"
508 with open(fname, "wb") as a, open(fname, "wb") as b:
509 self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno()))
510
Florent Xiclunac9c79782010-03-08 12:24:53 +0000511
512class PosixCommonTest(test_genericpath.CommonTest):
513 pathmodule = posixpath
514 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
515
516
Brett Cannonb47243a2003-06-16 21:54:50 +0000517def test_main():
Florent Xiclunac9c79782010-03-08 12:24:53 +0000518 support.run_unittest(PosixPathTest, PosixCommonTest)
519
Brett Cannonb47243a2003-06-16 21:54:50 +0000520
521if __name__=="__main__":
522 test_main()