blob: 54de0cf51635ba0eb0a7323c9ff36f8a8ebce447 [file] [log] [blame]
Brett Cannonb47243a2003-06-16 21:54:50 +00001import unittest
Florent Xiclunac9c79782010-03-08 12:24:53 +00002from test import support, test_genericpath
Skip Montanaroe809b002000-07-12 00:20:08 +00003
Brian Curtind40e6f72010-07-08 21:39:08 +00004import posixpath
5import os
6import sys
Georg Brandl89fad142010-03-14 10:23:39 +00007from posixpath import realpath, abspath, dirname, basename
Johannes Gijsbers4ec40642004-08-14 15:01:53 +00008
Michael Foord07926f02011-03-16 17:19:16 -04009try:
10 import posix
11except ImportError:
12 posix = None
13
Johannes Gijsbers4ec40642004-08-14 15:01:53 +000014# An absolute path to a temporary filename for testing. We can't rely on TESTFN
15# being an absolute path, so we need this.
16
Benjamin Petersonee8712c2008-05-20 21:35:26 +000017ABSTFN = abspath(support.TESTFN)
Skip Montanaroe809b002000-07-12 00:20:08 +000018
Brian Curtind40e6f72010-07-08 21:39:08 +000019def skip_if_ABSTFN_contains_backslash(test):
20 """
21 On Windows, posixpath.abspath still returns paths with backslashes
22 instead of posix forward slashes. If this is the case, several tests
23 fail, so skip them.
24 """
25 found_backslash = '\\' in ABSTFN
26 msg = "ABSTFN is not a posix path - tests fail"
27 return [test, unittest.skip(msg)(test)][found_backslash]
28
Guido van Rossumd8faa362007-04-27 19:54:29 +000029def safe_rmdir(dirname):
30 try:
31 os.rmdir(dirname)
32 except OSError:
33 pass
34
Brett Cannonb47243a2003-06-16 21:54:50 +000035class PosixPathTest(unittest.TestCase):
Skip Montanaroe809b002000-07-12 00:20:08 +000036
Guido van Rossumd8faa362007-04-27 19:54:29 +000037 def setUp(self):
38 self.tearDown()
39
40 def tearDown(self):
41 for suffix in ["", "1", "2"]:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000042 support.unlink(support.TESTFN + suffix)
43 safe_rmdir(support.TESTFN + suffix)
Guido van Rossumd8faa362007-04-27 19:54:29 +000044
Brett Cannonb47243a2003-06-16 21:54:50 +000045 def test_join(self):
Guido van Rossumf0af3e32008-10-02 18:55:37 +000046 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"),
47 "/bar/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +000048 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
Guido van Rossumf0af3e32008-10-02 18:55:37 +000049 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"),
50 "/foo/bar/baz/")
51
52 self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"),
53 b"/bar/baz")
54 self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"),
55 b"/foo/bar/baz")
56 self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"),
57 b"/foo/bar/baz/")
Skip Montanaroe809b002000-07-12 00:20:08 +000058
Hynek Schlawack47749462012-07-15 16:21:30 +020059 with self.assertRaises(TypeError) as e:
60 posixpath.join(b'bytes', 'str')
61 self.assertIn("Can't mix strings and bytes", e.args[0])
62 with self.assertRaises(TypeError) as e:
63 posixpath.join('str', b'bytes')
64 self.assertIn("Can't mix strings and bytes", e.args[0])
65 with self.assertRaises(TypeError) as e:
66 posixpath.join('str', bytearray(b'bytes'))
67 self.assertIn("Can't mix strings and bytes", e.args[0])
Skip Montanaroe809b002000-07-12 00:20:08 +000068
Brett Cannonb47243a2003-06-16 21:54:50 +000069 def test_split(self):
70 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
71 self.assertEqual(posixpath.split("/"), ("/", ""))
72 self.assertEqual(posixpath.split("foo"), ("", "foo"))
73 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
74 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
75
Guido van Rossumf0af3e32008-10-02 18:55:37 +000076 self.assertEqual(posixpath.split(b"/foo/bar"), (b"/foo", b"bar"))
77 self.assertEqual(posixpath.split(b"/"), (b"/", b""))
78 self.assertEqual(posixpath.split(b"foo"), (b"", b"foo"))
79 self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo"))
80 self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar"))
81
Guido van Rossumd8faa362007-04-27 19:54:29 +000082 def splitextTest(self, path, filename, ext):
83 self.assertEqual(posixpath.splitext(path), (filename, ext))
84 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext))
Guido van Rossumf0af3e32008-10-02 18:55:37 +000085 self.assertEqual(posixpath.splitext("abc/" + path),
86 ("abc/" + filename, ext))
87 self.assertEqual(posixpath.splitext("abc.def/" + path),
88 ("abc.def/" + filename, ext))
89 self.assertEqual(posixpath.splitext("/abc.def/" + path),
90 ("/abc.def/" + filename, ext))
91 self.assertEqual(posixpath.splitext(path + "/"),
92 (filename + ext + "/", ""))
93
94 path = bytes(path, "ASCII")
95 filename = bytes(filename, "ASCII")
96 ext = bytes(ext, "ASCII")
97
98 self.assertEqual(posixpath.splitext(path), (filename, ext))
99 self.assertEqual(posixpath.splitext(b"/" + path),
100 (b"/" + filename, ext))
101 self.assertEqual(posixpath.splitext(b"abc/" + path),
102 (b"abc/" + filename, ext))
103 self.assertEqual(posixpath.splitext(b"abc.def/" + path),
104 (b"abc.def/" + filename, ext))
105 self.assertEqual(posixpath.splitext(b"/abc.def/" + path),
106 (b"/abc.def/" + filename, ext))
107 self.assertEqual(posixpath.splitext(path + b"/"),
108 (filename + ext + b"/", b""))
Brett Cannonb47243a2003-06-16 21:54:50 +0000109
Guido van Rossumd8faa362007-04-27 19:54:29 +0000110 def test_splitext(self):
111 self.splitextTest("foo.bar", "foo", ".bar")
112 self.splitextTest("foo.boo.bar", "foo.boo", ".bar")
113 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar")
114 self.splitextTest(".csh.rc", ".csh", ".rc")
115 self.splitextTest("nodots", "nodots", "")
116 self.splitextTest(".cshrc", ".cshrc", "")
117 self.splitextTest("...manydots", "...manydots", "")
118 self.splitextTest("...manydots.ext", "...manydots", ".ext")
119 self.splitextTest(".", ".", "")
120 self.splitextTest("..", "..", "")
121 self.splitextTest("........", "........", "")
122 self.splitextTest("", "", "")
Brett Cannonb47243a2003-06-16 21:54:50 +0000123
124 def test_isabs(self):
125 self.assertIs(posixpath.isabs(""), False)
126 self.assertIs(posixpath.isabs("/"), True)
127 self.assertIs(posixpath.isabs("/foo"), True)
128 self.assertIs(posixpath.isabs("/foo/bar"), True)
129 self.assertIs(posixpath.isabs("foo/bar"), False)
130
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000131 self.assertIs(posixpath.isabs(b""), False)
132 self.assertIs(posixpath.isabs(b"/"), True)
133 self.assertIs(posixpath.isabs(b"/foo"), True)
134 self.assertIs(posixpath.isabs(b"/foo/bar"), True)
135 self.assertIs(posixpath.isabs(b"foo/bar"), False)
136
Brett Cannonb47243a2003-06-16 21:54:50 +0000137 def test_basename(self):
138 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
139 self.assertEqual(posixpath.basename("/"), "")
140 self.assertEqual(posixpath.basename("foo"), "foo")
141 self.assertEqual(posixpath.basename("////foo"), "foo")
142 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
143
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000144 self.assertEqual(posixpath.basename(b"/foo/bar"), b"bar")
145 self.assertEqual(posixpath.basename(b"/"), b"")
146 self.assertEqual(posixpath.basename(b"foo"), b"foo")
147 self.assertEqual(posixpath.basename(b"////foo"), b"foo")
148 self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar")
149
Brett Cannonb47243a2003-06-16 21:54:50 +0000150 def test_dirname(self):
151 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
152 self.assertEqual(posixpath.dirname("/"), "/")
153 self.assertEqual(posixpath.dirname("foo"), "")
154 self.assertEqual(posixpath.dirname("////foo"), "////")
155 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
156
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000157 self.assertEqual(posixpath.dirname(b"/foo/bar"), b"/foo")
158 self.assertEqual(posixpath.dirname(b"/"), b"/")
159 self.assertEqual(posixpath.dirname(b"foo"), b"")
160 self.assertEqual(posixpath.dirname(b"////foo"), b"////")
161 self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo")
162
Brett Cannonb47243a2003-06-16 21:54:50 +0000163 def test_islink(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000164 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Michael Foord07926f02011-03-16 17:19:16 -0400165 self.assertIs(posixpath.lexists(support.TESTFN + "2"), False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000166 f = open(support.TESTFN + "1", "wb")
Brett Cannonb47243a2003-06-16 21:54:50 +0000167 try:
Guido van Rossum7dcb8442007-08-27 23:26:56 +0000168 f.write(b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000169 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000170 self.assertIs(posixpath.islink(support.TESTFN + "1"), False)
Brian Curtin3b4499c2010-12-28 14:31:47 +0000171 if support.can_symlink():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000172 os.symlink(support.TESTFN + "1", support.TESTFN + "2")
173 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
174 os.remove(support.TESTFN + "1")
175 self.assertIs(posixpath.islink(support.TESTFN + "2"), True)
176 self.assertIs(posixpath.exists(support.TESTFN + "2"), False)
177 self.assertIs(posixpath.lexists(support.TESTFN + "2"), True)
Brett Cannonb47243a2003-06-16 21:54:50 +0000178 finally:
179 if not f.close():
180 f.close()
Brett Cannonb47243a2003-06-16 21:54:50 +0000181
Brian Curtind40e6f72010-07-08 21:39:08 +0000182 @staticmethod
183 def _create_file(filename):
184 with open(filename, 'wb') as f:
185 f.write(b'foo')
186
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187 def test_samefile(self):
Brian Curtind40e6f72010-07-08 21:39:08 +0000188 test_fn = support.TESTFN + "1"
189 self._create_file(test_fn)
190 self.assertTrue(posixpath.samefile(test_fn, test_fn))
191 self.assertRaises(TypeError, posixpath.samefile)
192
193 @unittest.skipIf(
194 sys.platform.startswith('win'),
195 "posixpath.samefile does not work on links in Windows")
Brian Curtin52173d42010-12-02 18:29:18 +0000196 @unittest.skipUnless(hasattr(os, "symlink"),
197 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000198 def test_samefile_on_links(self):
199 test_fn1 = support.TESTFN + "1"
200 test_fn2 = support.TESTFN + "2"
201 self._create_file(test_fn1)
202
203 os.symlink(test_fn1, test_fn2)
204 self.assertTrue(posixpath.samefile(test_fn1, test_fn2))
205 os.remove(test_fn2)
206
207 self._create_file(test_fn2)
208 self.assertFalse(posixpath.samefile(test_fn1, test_fn2))
209
Brett Cannonb47243a2003-06-16 21:54:50 +0000210
Brett Cannonb47243a2003-06-16 21:54:50 +0000211 def test_samestat(self):
Brian Curtind40e6f72010-07-08 21:39:08 +0000212 test_fn = support.TESTFN + "1"
213 self._create_file(test_fn)
214 test_fns = [test_fn]*2
215 stats = map(os.stat, test_fns)
216 self.assertTrue(posixpath.samestat(*stats))
217
218 @unittest.skipIf(
219 sys.platform.startswith('win'),
220 "posixpath.samestat does not work on links in Windows")
Brian Curtin52173d42010-12-02 18:29:18 +0000221 @unittest.skipUnless(hasattr(os, "symlink"),
222 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000223 def test_samestat_on_links(self):
224 test_fn1 = support.TESTFN + "1"
225 test_fn2 = support.TESTFN + "2"
Brian Curtin16633fa2010-07-09 13:54:27 +0000226 self._create_file(test_fn1)
Brian Curtind40e6f72010-07-08 21:39:08 +0000227 test_fns = (test_fn1, test_fn2)
228 os.symlink(*test_fns)
229 stats = map(os.stat, test_fns)
230 self.assertTrue(posixpath.samestat(*stats))
231 os.remove(test_fn2)
232
233 self._create_file(test_fn2)
234 stats = map(os.stat, test_fns)
235 self.assertFalse(posixpath.samestat(*stats))
236
237 self.assertRaises(TypeError, posixpath.samestat)
Brett Cannonb47243a2003-06-16 21:54:50 +0000238
Brett Cannonb47243a2003-06-16 21:54:50 +0000239 def test_ismount(self):
240 self.assertIs(posixpath.ismount("/"), True)
Michael Foord07926f02011-03-16 17:19:16 -0400241 self.assertIs(posixpath.ismount(b"/"), True)
242
243 def test_ismount_non_existent(self):
244 # Non-existent mountpoint.
245 self.assertIs(posixpath.ismount(ABSTFN), False)
246 try:
247 os.mkdir(ABSTFN)
248 self.assertIs(posixpath.ismount(ABSTFN), False)
249 finally:
250 safe_rmdir(ABSTFN)
251
252 @unittest.skipUnless(support.can_symlink(),
253 "Test requires symlink support")
254 def test_ismount_symlinks(self):
255 # Symlinks are never mountpoints.
256 try:
257 os.symlink("/", ABSTFN)
258 self.assertIs(posixpath.ismount(ABSTFN), False)
259 finally:
260 os.unlink(ABSTFN)
261
262 @unittest.skipIf(posix is None, "Test requires posix module")
263 def test_ismount_different_device(self):
264 # Simulate the path being on a different device from its parent by
265 # mocking out st_dev.
266 save_lstat = os.lstat
267 def fake_lstat(path):
268 st_ino = 0
269 st_dev = 0
270 if path == ABSTFN:
271 st_dev = 1
272 st_ino = 1
273 return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0))
274 try:
275 os.lstat = fake_lstat
276 self.assertIs(posixpath.ismount(ABSTFN), True)
277 finally:
278 os.lstat = save_lstat
Brett Cannonb47243a2003-06-16 21:54:50 +0000279
Brett Cannonb47243a2003-06-16 21:54:50 +0000280 def test_expanduser(self):
281 self.assertEqual(posixpath.expanduser("foo"), "foo")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000282 self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000283 try:
284 import pwd
285 except ImportError:
286 pass
287 else:
Ezio Melottie9615932010-01-24 19:26:24 +0000288 self.assertIsInstance(posixpath.expanduser("~/"), str)
289 self.assertIsInstance(posixpath.expanduser(b"~/"), bytes)
Neal Norwitz168e73d2003-07-01 03:33:31 +0000290 # if home directory == root directory, this test makes no sense
291 if posixpath.expanduser("~") != '/':
292 self.assertEqual(
293 posixpath.expanduser("~") + "/",
294 posixpath.expanduser("~/")
295 )
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000296 self.assertEqual(
297 posixpath.expanduser(b"~") + b"/",
298 posixpath.expanduser(b"~/")
299 )
Ezio Melottie9615932010-01-24 19:26:24 +0000300 self.assertIsInstance(posixpath.expanduser("~root/"), str)
301 self.assertIsInstance(posixpath.expanduser("~foo/"), str)
302 self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes)
303 self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
Brett Cannonb47243a2003-06-16 21:54:50 +0000304
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000305 with support.EnvironmentVarGuard() as env:
Walter Dörwald155374d2009-05-01 19:58:58 +0000306 env['HOME'] = '/'
Walter Dörwaldb525e182009-04-26 21:39:21 +0000307 self.assertEqual(posixpath.expanduser("~"), "/")
Jesus Cea7f0d8882012-05-10 05:10:50 +0200308 self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
Michael Foord07926f02011-03-16 17:19:16 -0400309 # expanduser should fall back to using the password database
310 del env['HOME']
311 home = pwd.getpwuid(os.getuid()).pw_dir
312 self.assertEqual(posixpath.expanduser("~"), home)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000313
Brett Cannonb47243a2003-06-16 21:54:50 +0000314 def test_normpath(self):
315 self.assertEqual(posixpath.normpath(""), ".")
316 self.assertEqual(posixpath.normpath("/"), "/")
317 self.assertEqual(posixpath.normpath("//"), "//")
318 self.assertEqual(posixpath.normpath("///"), "/")
319 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000320 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"),
321 "/foo/baz")
Brett Cannonb47243a2003-06-16 21:54:50 +0000322 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
323
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000324 self.assertEqual(posixpath.normpath(b""), b".")
325 self.assertEqual(posixpath.normpath(b"/"), b"/")
326 self.assertEqual(posixpath.normpath(b"//"), b"//")
327 self.assertEqual(posixpath.normpath(b"///"), b"/")
328 self.assertEqual(posixpath.normpath(b"///foo/.//bar//"), b"/foo/bar")
329 self.assertEqual(posixpath.normpath(b"///foo/.//bar//.//..//.//baz"),
330 b"/foo/baz")
331 self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"),
332 b"/foo/bar")
333
Brian Curtin52173d42010-12-02 18:29:18 +0000334 @unittest.skipUnless(hasattr(os, "symlink"),
335 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000336 @skip_if_ABSTFN_contains_backslash
337 def test_realpath_basic(self):
338 # Basic operation.
339 try:
340 os.symlink(ABSTFN+"1", ABSTFN)
341 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
342 finally:
343 support.unlink(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000344
Brian Curtin52173d42010-12-02 18:29:18 +0000345 @unittest.skipUnless(hasattr(os, "symlink"),
346 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000347 @skip_if_ABSTFN_contains_backslash
Michael Foord07926f02011-03-16 17:19:16 -0400348 def test_realpath_relative(self):
349 try:
350 os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
351 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
352 finally:
353 support.unlink(ABSTFN)
354
355 @unittest.skipUnless(hasattr(os, "symlink"),
356 "Missing symlink implementation")
357 @skip_if_ABSTFN_contains_backslash
Brian Curtind40e6f72010-07-08 21:39:08 +0000358 def test_realpath_symlink_loops(self):
359 # Bug #930024, return the path unchanged if we get into an infinite
360 # symlink loop.
361 try:
362 old_path = abspath('.')
363 os.symlink(ABSTFN, ABSTFN)
364 self.assertEqual(realpath(ABSTFN), ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000365
Brian Curtind40e6f72010-07-08 21:39:08 +0000366 os.symlink(ABSTFN+"1", ABSTFN+"2")
367 os.symlink(ABSTFN+"2", ABSTFN+"1")
368 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
369 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000370
Brian Curtind40e6f72010-07-08 21:39:08 +0000371 # Test using relative path as well.
372 os.chdir(dirname(ABSTFN))
373 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
374 finally:
375 os.chdir(old_path)
376 support.unlink(ABSTFN)
377 support.unlink(ABSTFN+"1")
378 support.unlink(ABSTFN+"2")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000379
Brian Curtin52173d42010-12-02 18:29:18 +0000380 @unittest.skipUnless(hasattr(os, "symlink"),
381 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000382 @skip_if_ABSTFN_contains_backslash
383 def test_realpath_resolve_parents(self):
384 # We also need to resolve any symlinks in the parents of a relative
385 # path passed to realpath. E.g.: current working directory is
386 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
387 # realpath("a"). This should return /usr/share/doc/a/.
388 try:
389 old_path = abspath('.')
390 os.mkdir(ABSTFN)
391 os.mkdir(ABSTFN + "/y")
392 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000393
Brian Curtind40e6f72010-07-08 21:39:08 +0000394 os.chdir(ABSTFN + "/k")
395 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
396 finally:
397 os.chdir(old_path)
398 support.unlink(ABSTFN + "/k")
399 safe_rmdir(ABSTFN + "/y")
400 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000401
Brian Curtin52173d42010-12-02 18:29:18 +0000402 @unittest.skipUnless(hasattr(os, "symlink"),
403 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000404 @skip_if_ABSTFN_contains_backslash
405 def test_realpath_resolve_before_normalizing(self):
406 # Bug #990669: Symbolic links should be resolved before we
407 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
408 # in the following hierarchy:
409 # a/k/y
410 #
411 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
412 # then realpath("link-y/..") should return 'k', not 'a'.
413 try:
414 old_path = abspath('.')
415 os.mkdir(ABSTFN)
416 os.mkdir(ABSTFN + "/k")
417 os.mkdir(ABSTFN + "/k/y")
418 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000419
Brian Curtind40e6f72010-07-08 21:39:08 +0000420 # Absolute path.
421 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
422 # Relative path.
423 os.chdir(dirname(ABSTFN))
424 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."),
425 ABSTFN + "/k")
426 finally:
427 os.chdir(old_path)
428 support.unlink(ABSTFN + "/link-y")
429 safe_rmdir(ABSTFN + "/k/y")
430 safe_rmdir(ABSTFN + "/k")
431 safe_rmdir(ABSTFN)
Tim Peters5d36a552005-06-03 22:40:27 +0000432
Brian Curtin52173d42010-12-02 18:29:18 +0000433 @unittest.skipUnless(hasattr(os, "symlink"),
434 "Missing symlink implementation")
Brian Curtind40e6f72010-07-08 21:39:08 +0000435 @skip_if_ABSTFN_contains_backslash
436 def test_realpath_resolve_first(self):
437 # Bug #1213894: The first component of the path, if not absolute,
438 # must be resolved too.
Georg Brandl268e61c2005-06-03 14:28:50 +0000439
Brian Curtind40e6f72010-07-08 21:39:08 +0000440 try:
441 old_path = abspath('.')
442 os.mkdir(ABSTFN)
443 os.mkdir(ABSTFN + "/k")
444 os.symlink(ABSTFN, ABSTFN + "link")
445 os.chdir(dirname(ABSTFN))
Tim Peters5d36a552005-06-03 22:40:27 +0000446
Brian Curtind40e6f72010-07-08 21:39:08 +0000447 base = basename(ABSTFN)
448 self.assertEqual(realpath(base + "link"), ABSTFN)
449 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
450 finally:
451 os.chdir(old_path)
452 support.unlink(ABSTFN + "link")
453 safe_rmdir(ABSTFN + "/k")
454 safe_rmdir(ABSTFN)
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000455
Guido van Rossumd8faa362007-04-27 19:54:29 +0000456 def test_relpath(self):
457 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
458 try:
459 curdir = os.path.split(os.getcwd())[-1]
460 self.assertRaises(ValueError, posixpath.relpath, "")
461 self.assertEqual(posixpath.relpath("a"), "a")
462 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a")
463 self.assertEqual(posixpath.relpath("a/b"), "a/b")
464 self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
465 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a")
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000466 self.assertEqual(posixpath.relpath("a/b", "../c"),
467 "../"+curdir+"/a/b")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000468 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
Christian Heimesfaf2f632008-01-06 16:59:19 +0000469 self.assertEqual(posixpath.relpath("a", "a"), ".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000470 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat')
471 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat')
472 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat')
473 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..')
474 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat')
475 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x')
476 self.assertEqual(posixpath.relpath("/", "/"), '.')
477 self.assertEqual(posixpath.relpath("/a", "/a"), '.')
478 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000479 finally:
480 os.getcwd = real_getcwd
Brett Cannonb47243a2003-06-16 21:54:50 +0000481
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000482 def test_relpath_bytes(self):
483 (real_getcwdb, os.getcwdb) = (os.getcwdb, lambda: br"/home/user/bar")
484 try:
485 curdir = os.path.split(os.getcwdb())[-1]
486 self.assertRaises(ValueError, posixpath.relpath, b"")
487 self.assertEqual(posixpath.relpath(b"a"), b"a")
488 self.assertEqual(posixpath.relpath(posixpath.abspath(b"a")), b"a")
489 self.assertEqual(posixpath.relpath(b"a/b"), b"a/b")
490 self.assertEqual(posixpath.relpath(b"../a/b"), b"../a/b")
491 self.assertEqual(posixpath.relpath(b"a", b"../b"),
492 b"../"+curdir+b"/a")
493 self.assertEqual(posixpath.relpath(b"a/b", b"../c"),
494 b"../"+curdir+b"/a/b")
495 self.assertEqual(posixpath.relpath(b"a", b"b/c"), b"../../a")
496 self.assertEqual(posixpath.relpath(b"a", b"a"), b".")
Hirokazu Yamamotob08820a2010-10-18 12:13:18 +0000497 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x/y/z"), b'../../../foo/bar/bat')
498 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/foo/bar"), b'bat')
499 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/"), b'foo/bar/bat')
500 self.assertEqual(posixpath.relpath(b"/", b"/foo/bar/bat"), b'../../..')
501 self.assertEqual(posixpath.relpath(b"/foo/bar/bat", b"/x"), b'../foo/bar/bat')
502 self.assertEqual(posixpath.relpath(b"/x", b"/foo/bar/bat"), b'../../../x')
503 self.assertEqual(posixpath.relpath(b"/", b"/"), b'.')
504 self.assertEqual(posixpath.relpath(b"/a", b"/a"), b'.')
505 self.assertEqual(posixpath.relpath(b"/a/b", b"/a/b"), b'.')
Guido van Rossumf0af3e32008-10-02 18:55:37 +0000506
507 self.assertRaises(TypeError, posixpath.relpath, b"bytes", "str")
508 self.assertRaises(TypeError, posixpath.relpath, "str", b"bytes")
509 finally:
510 os.getcwdb = real_getcwdb
511
Michael Foord07926f02011-03-16 17:19:16 -0400512 def test_sameopenfile(self):
513 fname = support.TESTFN + "1"
514 with open(fname, "wb") as a, open(fname, "wb") as b:
515 self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno()))
516
Florent Xiclunac9c79782010-03-08 12:24:53 +0000517
518class PosixCommonTest(test_genericpath.CommonTest):
519 pathmodule = posixpath
520 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
521
522
Brett Cannonb47243a2003-06-16 21:54:50 +0000523def test_main():
Florent Xiclunac9c79782010-03-08 12:24:53 +0000524 support.run_unittest(PosixPathTest, PosixCommonTest)
525
Brett Cannonb47243a2003-06-16 21:54:50 +0000526
527if __name__=="__main__":
528 test_main()