blob: daebeaa8ee42cff1b3563c89d8b5bb9e7b88bbed [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("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200303 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400304 # expanduser should fall back to using the password database
305 del env['HOME']
306 home = pwd.getpwuid(os.getuid()).pw_dir
307 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000308
Brett Cannonb47243a2003-06-16 21:54:50 +0000309 def test_normpath(self):
310 self.assertEqual(posixpath.normpath(""), ".")
311 self.assertEqual(posixpath.normpath("/"), "/")
312 self.assertEqual(posixpath.normpath("//"), "//")
313 self.assertEqual(posixpath.normpath("///"), "/")
314 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000315 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
316 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000317 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
318
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000319 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"///"), b"/")
323 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
324 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
325 b"/foo/baz")
326 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
327 b"/foo/bar")
328
Brian Curtin52173d42010-12-02 18:29:18 +0000329 @unittest.skipUnless(hasattr(os, "symlink"),
330 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000331 @skip_if_ABSTFN_contains_backslash
332 def test_realpath_basic(self):
333 # Basic operation.
334 try:
335 os.symlink(ABSTFN+"1", ABSTFN)
336 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
337 finally:
338 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000339
Brian Curtin52173d42010-12-02 18:29:18 +0000340 @unittest.skipUnless(hasattr(os, "symlink"),
341 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000342 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400343 def test_realpath_relative(self):
344 try:
345 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
346 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
347 finally:
348 support.unlink(ABSTFN)
349
350 @unittest.skipUnless(hasattr(os, "symlink"),
351 "Missing symlink implementation")
352 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000353 def test_realpath_symlink_loops(self):
354 # Bug #930024, return the path unchanged if we get into an infinite
355 # symlink loop.
356 try:
357 old_path = abspath('.')
358 os.symlink(ABSTFN, ABSTFN)
359 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000360
Brian Curtind40e6f72010-07-08 21:39:08 +0000361 os.symlink(ABSTFN+"1", ABSTFN+"2")
362 os.symlink(ABSTFN+"2", ABSTFN+"1")
363 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
364 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000365
Brian Curtind40e6f72010-07-08 21:39:08 +0000366 # Test using relative path as well.
367 os.chdir(dirname(ABSTFN))
368 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
369 finally:
370 os.chdir(old_path)
371 support.unlink(ABSTFN)
372 support.unlink(ABSTFN+"1")
373 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000374
Brian Curtin52173d42010-12-02 18:29:18 +0000375 @unittest.skipUnless(hasattr(os, "symlink"),
376 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000377 @skip_if_ABSTFN_contains_backslash
378 def test_realpath_resolve_parents(self):
379 # We also need to resolve any symlinks in the parents of a relative
380 # path passed to realpath. E.g.: current working directory is
381 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
382 # realpath("a"). This should return /usr/share/doc/a/.
383 try:
384 old_path = abspath('.')
385 os.mkdir(ABSTFN)
386 os.mkdir(ABSTFN + "/y")
387 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000388
Brian Curtind40e6f72010-07-08 21:39:08 +0000389 os.chdir(ABSTFN + "/k")
390 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
391 finally:
392 os.chdir(old_path)
393 support.unlink(ABSTFN + "/k")
394 safe_rmdir(ABSTFN + "/y")
395 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000396
Brian Curtin52173d42010-12-02 18:29:18 +0000397 @unittest.skipUnless(hasattr(os, "symlink"),
398 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000399 @skip_if_ABSTFN_contains_backslash
400 def test_realpath_resolve_before_normalizing(self):
401 # Bug #990669: Symbolic links should be resolved before we
402 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
403 # in the following hierarchy:
404 # a/k/y
405 #
406 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
407 # then realpath("link-y/..") should return 'k', not 'a'.
408 try:
409 old_path = abspath('.')
410 os.mkdir(ABSTFN)
411 os.mkdir(ABSTFN + "/k")
412 os.mkdir(ABSTFN + "/k/y")
413 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000414
Brian Curtind40e6f72010-07-08 21:39:08 +0000415 # Absolute path.
416 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
417 # Relative path.
418 os.chdir(dirname(ABSTFN))
419 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
420 ABSTFN + "/k")
421 finally:
422 os.chdir(old_path)
423 support.unlink(ABSTFN + "/link-y")
424 safe_rmdir(ABSTFN + "/k/y")
425 safe_rmdir(ABSTFN + "/k")
426 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000427
Brian Curtin52173d42010-12-02 18:29:18 +0000428 @unittest.skipUnless(hasattr(os, "symlink"),
429 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000430 @skip_if_ABSTFN_contains_backslash
431 def test_realpath_resolve_first(self):
432 # Bug #1213894: The first component of the path, if not absolute,
433 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000434
Brian Curtind40e6f72010-07-08 21:39:08 +0000435 try:
436 old_path = abspath('.')
437 os.mkdir(ABSTFN)
438 os.mkdir(ABSTFN + "/k")
439 os.symlink(ABSTFN, ABSTFN + "link")
440 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000441
Brian Curtind40e6f72010-07-08 21:39:08 +0000442 base = basename(ABSTFN)
443 self.assertEqual(realpath(base + "link"), ABSTFN)
444 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
445 finally:
446 os.chdir(old_path)
447 support.unlink(ABSTFN + "link")
448 safe_rmdir(ABSTFN + "/k")
449 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000450
Guido van Rossumd8faa362007-04-27 19:54:29 +0000451 def test_relpath(self):
452 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
453 try:
454 curdir = os.path.split(os.getcwd())[-1]
455 self.assertRaises(ValueError, posixpath.relpath, "")
456 self.assertEqual(posixpath.relpath("a"), "a")
457 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
458 self.assertEqual(posixpath.relpath("a/b"), "a/b")
459 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
460 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000461 self.assertEqual(posixpath.relpath("a/b", "../c"),
462 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000463 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000464 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000465 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
466 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
467 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
468 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
469 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
470 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
471 self.assertEqual(posixpath.relpath("/", "/"), '.')
472 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
473 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000474 finally:
475 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000476
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000477 def test_relpath_bytes(self):
478 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
479 try:
480 curdir = os.path.split(os.getcwdb())[-1]
481 self.assertRaises(ValueError, posixpath.relpath, b"")
482 self.assertEqual(posixpath.relpath(b"a"), b"a")
483 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
484 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
485 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
486 self.assertEqual(posixpath.relpath(b"a", b"../b"),
487 b"../"+curdir+b"/a")
488 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
489 b"../"+curdir+b"/a/b")
490 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
491 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000492 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
493 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
494 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
495 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
496 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
497 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
498 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
499 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
500 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000501
502 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
503 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
504 finally:
505 os.getcwdb = real_getcwdb
506
Michael Foord07926f02011-03-16 17:19:16 -0400507 def test_sameopenfile(self):
508 fname = support.TESTFN + "1"
509 with open(fname, "wb") as a, open(fname, "wb") as b:
510 self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno()))
511
Florent Xiclunac9c79782010-03-08 12:24:53 +0000512
513class PosixCommonTest(test_genericpath.CommonTest):
514 pathmodule = posixpath
515 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
516
517
Brett Cannonb47243a2003-06-16 21:54:50 +0000518def test_main():
Florent Xiclunac9c79782010-03-08 12:24:53 +0000519 support.run_unittest(PosixPathTest, PosixCommonTest)
520
Brett Cannonb47243a2003-06-16 21:54:50 +0000521
522if __name__=="__main__":
523 test_main()