blob: 1fc3e7c4a6174a54c838cc771993bfe420dfedd3 [file] [log] [blame]
Brett Cannonb47243a2003-06-16 21:54:50 +00001import unittest
2from test import test_support
Skip Montanaroe809b002000-07-12 00:20:08 +00003
Brett Cannonb47243a2003-06-16 21:54:50 +00004import posixpath, os
Johannes Gijsbers4ec40642004-08-14 15:01:53 +00005from posixpath import realpath, abspath, join, dirname, basename
6
7# An absolute path to a temporary filename for testing. We can't rely on TESTFN
8# being an absolute path, so we need this.
9
10ABSTFN = abspath(test_support.TESTFN)
Skip Montanaroe809b002000-07-12 00:20:08 +000011
Brett Cannonb47243a2003-06-16 21:54:50 +000012class PosixPathTest(unittest.TestCase):
Skip Montanaroe809b002000-07-12 00:20:08 +000013
Brett Cannonb47243a2003-06-16 21:54:50 +000014 def assertIs(self, a, b):
15 self.assert_(a is b)
Skip Montanaroe809b002000-07-12 00:20:08 +000016
Brett Cannonb47243a2003-06-16 21:54:50 +000017 def test_normcase(self):
18 # Check that normcase() is idempotent
19 p = "FoO/./BaR"
20 p = posixpath.normcase(p)
21 self.assertEqual(p, posixpath.normcase(p))
Skip Montanaroe809b002000-07-12 00:20:08 +000022
Brett Cannonb47243a2003-06-16 21:54:50 +000023 self.assertRaises(TypeError, posixpath.normcase)
Skip Montanaroe809b002000-07-12 00:20:08 +000024
Brett Cannonb47243a2003-06-16 21:54:50 +000025 def test_join(self):
26 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"), "/bar/baz")
27 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
28 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"), "/foo/bar/baz/")
Skip Montanaroe809b002000-07-12 00:20:08 +000029
Brett Cannonb47243a2003-06-16 21:54:50 +000030 self.assertRaises(TypeError, posixpath.join)
Skip Montanaroe809b002000-07-12 00:20:08 +000031
Brett Cannonb47243a2003-06-16 21:54:50 +000032 def test_splitdrive(self):
33 self.assertEqual(posixpath.splitdrive("/foo/bar"), ("", "/foo/bar"))
34
35 self.assertRaises(TypeError, posixpath.splitdrive)
36
37 def test_split(self):
38 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
39 self.assertEqual(posixpath.split("/"), ("/", ""))
40 self.assertEqual(posixpath.split("foo"), ("", "foo"))
41 self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
42 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
43
44 self.assertRaises(TypeError, posixpath.split)
45
46 def test_splitext(self):
47 self.assertEqual(posixpath.splitext("foo.ext"), ("foo", ".ext"))
48 self.assertEqual(posixpath.splitext("/foo/foo.ext"), ("/foo/foo", ".ext"))
49 self.assertEqual(posixpath.splitext(".ext"), ("", ".ext"))
50 self.assertEqual(posixpath.splitext("/foo.ext/foo"), ("/foo.ext/foo", ""))
51 self.assertEqual(posixpath.splitext("foo.ext/"), ("foo.ext/", ""))
52 self.assertEqual(posixpath.splitext(""), ("", ""))
53 self.assertEqual(posixpath.splitext("foo.bar.ext"), ("foo.bar", ".ext"))
54
55 self.assertRaises(TypeError, posixpath.splitext)
56
57 def test_isabs(self):
58 self.assertIs(posixpath.isabs(""), False)
59 self.assertIs(posixpath.isabs("/"), True)
60 self.assertIs(posixpath.isabs("/foo"), True)
61 self.assertIs(posixpath.isabs("/foo/bar"), True)
62 self.assertIs(posixpath.isabs("foo/bar"), False)
63
64 self.assertRaises(TypeError, posixpath.isabs)
65
66 def test_splitdrive(self):
67 self.assertEqual(posixpath.splitdrive("/foo/bar"), ("", "/foo/bar"))
68
69 self.assertRaises(TypeError, posixpath.splitdrive)
70
71 def test_basename(self):
72 self.assertEqual(posixpath.basename("/foo/bar"), "bar")
73 self.assertEqual(posixpath.basename("/"), "")
74 self.assertEqual(posixpath.basename("foo"), "foo")
75 self.assertEqual(posixpath.basename("////foo"), "foo")
76 self.assertEqual(posixpath.basename("//foo//bar"), "bar")
77
78 self.assertRaises(TypeError, posixpath.basename)
79
80 def test_dirname(self):
81 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
82 self.assertEqual(posixpath.dirname("/"), "/")
83 self.assertEqual(posixpath.dirname("foo"), "")
84 self.assertEqual(posixpath.dirname("////foo"), "////")
85 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
86
87 self.assertRaises(TypeError, posixpath.dirname)
88
89 def test_commonprefix(self):
90 self.assertEqual(
91 posixpath.commonprefix([]),
92 ""
93 )
94 self.assertEqual(
95 posixpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
96 "/home/swen"
97 )
98 self.assertEqual(
99 posixpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
100 "/home/swen/"
101 )
102 self.assertEqual(
103 posixpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]),
104 "/home/swen/spam"
105 )
106
107 def test_getsize(self):
108 f = open(test_support.TESTFN, "wb")
109 try:
110 f.write("foo")
111 f.close()
112 self.assertEqual(posixpath.getsize(test_support.TESTFN), 3)
113 finally:
114 if not f.closed:
115 f.close()
116 os.remove(test_support.TESTFN)
117
118 def test_time(self):
119 f = open(test_support.TESTFN, "wb")
120 try:
121 f.write("foo")
122 f.close()
123 f = open(test_support.TESTFN, "ab")
124 f.write("bar")
125 f.close()
126 f = open(test_support.TESTFN, "rb")
127 d = f.read()
128 f.close()
129 self.assertEqual(d, "foobar")
130
131 self.assert_(
132 posixpath.getctime(test_support.TESTFN) <=
133 posixpath.getmtime(test_support.TESTFN)
134 )
135 finally:
136 if not f.closed:
137 f.close()
138 os.remove(test_support.TESTFN)
139
140 def test_islink(self):
141 self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False)
142 f = open(test_support.TESTFN + "1", "wb")
143 try:
144 f.write("foo")
145 f.close()
146 self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False)
147 if hasattr(os, "symlink"):
148 os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2")
149 self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True)
150 os.remove(test_support.TESTFN + "1")
151 self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True)
152 self.assertIs(posixpath.exists(test_support.TESTFN + "2"), False)
153 finally:
154 if not f.close():
155 f.close()
156 try:
157 os.remove(test_support.TESTFN + "1")
158 except os.error:
159 pass
160 try:
161 os.remove(test_support.TESTFN + "2")
162 except os.error:
163 pass
164
165 self.assertRaises(TypeError, posixpath.islink)
166
167 def test_exists(self):
168 self.assertIs(posixpath.exists(test_support.TESTFN), False)
169 f = open(test_support.TESTFN, "wb")
170 try:
171 f.write("foo")
172 f.close()
173 self.assertIs(posixpath.exists(test_support.TESTFN), True)
174 finally:
175 if not f.close():
176 f.close()
177 try:
178 os.remove(test_support.TESTFN)
179 except os.error:
180 pass
181
182 self.assertRaises(TypeError, posixpath.exists)
183
184 def test_isdir(self):
185 self.assertIs(posixpath.isdir(test_support.TESTFN), False)
186 f = open(test_support.TESTFN, "wb")
187 try:
188 f.write("foo")
189 f.close()
190 self.assertIs(posixpath.isdir(test_support.TESTFN), False)
191 os.remove(test_support.TESTFN)
192 os.mkdir(test_support.TESTFN)
193 self.assertIs(posixpath.isdir(test_support.TESTFN), True)
194 os.rmdir(test_support.TESTFN)
195 finally:
196 if not f.close():
197 f.close()
198 try:
199 os.remove(test_support.TESTFN)
200 except os.error:
201 pass
202 try:
203 os.rmdir(test_support.TESTFN)
204 except os.error:
205 pass
206
207 self.assertRaises(TypeError, posixpath.isdir)
208
209 def test_isfile(self):
210 self.assertIs(posixpath.isfile(test_support.TESTFN), False)
211 f = open(test_support.TESTFN, "wb")
212 try:
213 f.write("foo")
214 f.close()
215 self.assertIs(posixpath.isfile(test_support.TESTFN), True)
216 os.remove(test_support.TESTFN)
217 os.mkdir(test_support.TESTFN)
218 self.assertIs(posixpath.isfile(test_support.TESTFN), False)
219 os.rmdir(test_support.TESTFN)
220 finally:
221 if not f.close():
222 f.close()
223 try:
224 os.remove(test_support.TESTFN)
225 except os.error:
226 pass
227 try:
228 os.rmdir(test_support.TESTFN)
229 except os.error:
230 pass
231
232 self.assertRaises(TypeError, posixpath.isdir)
233
234 def test_samefile(self):
235 f = open(test_support.TESTFN + "1", "wb")
236 try:
237 f.write("foo")
238 f.close()
239 self.assertIs(
240 posixpath.samefile(
241 test_support.TESTFN + "1",
242 test_support.TESTFN + "1"
243 ),
244 True
245 )
Tim Peters478c1052003-06-29 05:46:54 +0000246 # If we don't have links, assume that os.stat doesn't return resonable
Brett Cannonb47243a2003-06-16 21:54:50 +0000247 # inode information and thus, that samefile() doesn't work
248 if hasattr(os, "symlink"):
249 os.symlink(
250 test_support.TESTFN + "1",
251 test_support.TESTFN + "2"
252 )
253 self.assertIs(
254 posixpath.samefile(
255 test_support.TESTFN + "1",
256 test_support.TESTFN + "2"
257 ),
258 True
259 )
260 os.remove(test_support.TESTFN + "2")
261 f = open(test_support.TESTFN + "2", "wb")
262 f.write("bar")
263 f.close()
264 self.assertIs(
265 posixpath.samefile(
266 test_support.TESTFN + "1",
267 test_support.TESTFN + "2"
268 ),
269 False
270 )
271 finally:
272 if not f.close():
273 f.close()
274 try:
275 os.remove(test_support.TESTFN + "1")
276 except os.error:
277 pass
278 try:
279 os.remove(test_support.TESTFN + "2")
280 except os.error:
281 pass
282
283 self.assertRaises(TypeError, posixpath.samefile)
284
285 def test_samestat(self):
286 f = open(test_support.TESTFN + "1", "wb")
287 try:
288 f.write("foo")
289 f.close()
290 self.assertIs(
291 posixpath.samestat(
292 os.stat(test_support.TESTFN + "1"),
293 os.stat(test_support.TESTFN + "1")
294 ),
295 True
296 )
Tim Peters478c1052003-06-29 05:46:54 +0000297 # If we don't have links, assume that os.stat() doesn't return resonable
Brett Cannonb47243a2003-06-16 21:54:50 +0000298 # inode information and thus, that samefile() doesn't work
299 if hasattr(os, "symlink"):
300 if hasattr(os, "symlink"):
301 os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2")
302 self.assertIs(
303 posixpath.samestat(
304 os.stat(test_support.TESTFN + "1"),
305 os.stat(test_support.TESTFN + "2")
306 ),
307 True
308 )
309 os.remove(test_support.TESTFN + "2")
310 f = open(test_support.TESTFN + "2", "wb")
311 f.write("bar")
312 f.close()
313 self.assertIs(
314 posixpath.samestat(
315 os.stat(test_support.TESTFN + "1"),
316 os.stat(test_support.TESTFN + "2")
317 ),
318 False
319 )
320 finally:
321 if not f.close():
322 f.close()
323 try:
324 os.remove(test_support.TESTFN + "1")
325 except os.error:
326 pass
327 try:
328 os.remove(test_support.TESTFN + "2")
329 except os.error:
330 pass
331
332 self.assertRaises(TypeError, posixpath.samestat)
333
334 def test_ismount(self):
335 self.assertIs(posixpath.ismount("/"), True)
336
337 self.assertRaises(TypeError, posixpath.ismount)
338
339 def test_expanduser(self):
340 self.assertEqual(posixpath.expanduser("foo"), "foo")
Brett Cannonb47243a2003-06-16 21:54:50 +0000341 try:
342 import pwd
343 except ImportError:
344 pass
345 else:
Walter Dörwalda9da5ae2003-06-19 10:21:14 +0000346 self.assert_(isinstance(posixpath.expanduser("~/"), basestring))
Neal Norwitz168e73d2003-07-01 03:33:31 +0000347 # if home directory == root directory, this test makes no sense
348 if posixpath.expanduser("~") != '/':
349 self.assertEqual(
350 posixpath.expanduser("~") + "/",
351 posixpath.expanduser("~/")
352 )
Brett Cannonb47243a2003-06-16 21:54:50 +0000353 self.assert_(isinstance(posixpath.expanduser("~root/"), basestring))
354 self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring))
355
356 self.assertRaises(TypeError, posixpath.expanduser)
357
358 def test_expandvars(self):
359 oldenv = os.environ.copy()
360 try:
361 os.environ.clear()
362 os.environ["foo"] = "bar"
363 os.environ["{foo"] = "baz1"
364 os.environ["{foo}"] = "baz2"
365 self.assertEqual(posixpath.expandvars("foo"), "foo")
366 self.assertEqual(posixpath.expandvars("$foo bar"), "bar bar")
367 self.assertEqual(posixpath.expandvars("${foo}bar"), "barbar")
368 self.assertEqual(posixpath.expandvars("$[foo]bar"), "$[foo]bar")
369 self.assertEqual(posixpath.expandvars("$bar bar"), "$bar bar")
370 self.assertEqual(posixpath.expandvars("$?bar"), "$?bar")
371 self.assertEqual(posixpath.expandvars("${foo}bar"), "barbar")
372 self.assertEqual(posixpath.expandvars("$foo}bar"), "bar}bar")
373 self.assertEqual(posixpath.expandvars("${foo"), "${foo")
374 self.assertEqual(posixpath.expandvars("${{foo}}"), "baz1}")
375 finally:
376 os.environ.clear()
377 os.environ.update(oldenv)
378
379 self.assertRaises(TypeError, posixpath.expandvars)
380
381 def test_normpath(self):
382 self.assertEqual(posixpath.normpath(""), ".")
383 self.assertEqual(posixpath.normpath("/"), "/")
384 self.assertEqual(posixpath.normpath("//"), "//")
385 self.assertEqual(posixpath.normpath("///"), "/")
386 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
387 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"), "/foo/baz")
388 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
389
390 self.assertRaises(TypeError, posixpath.normpath)
391
392 def test_abspath(self):
393 self.assert_("foo" in posixpath.abspath("foo"))
394
395 self.assertRaises(TypeError, posixpath.abspath)
396
397 def test_realpath(self):
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000398 self.assert_("foo" in realpath("foo"))
Brett Cannonb47243a2003-06-16 21:54:50 +0000399 self.assertRaises(TypeError, posixpath.realpath)
Tim Petersa45cacf2004-08-20 03:47:14 +0000400
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000401 if hasattr(os, "symlink"):
402 def test_realpath_basic(self):
403 # Basic operation.
404 try:
405 os.symlink(ABSTFN+"1", ABSTFN)
406 self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
407 finally:
408 self.safe_remove(ABSTFN)
Tim Petersa45cacf2004-08-20 03:47:14 +0000409
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000410 def test_realpath_symlink_loops(self):
411 # Bug #930024, return the path unchanged if we get into an infinite
412 # symlink loop.
413 try:
414 old_path = abspath('.')
415 os.symlink(ABSTFN, ABSTFN)
416 self.assertEqual(realpath(ABSTFN), ABSTFN)
417
418 os.symlink(ABSTFN+"1", ABSTFN+"2")
419 os.symlink(ABSTFN+"2", ABSTFN+"1")
420 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
421 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
422
423 # Test using relative path as well.
424 os.chdir(dirname(ABSTFN))
425 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
426 finally:
427 os.chdir(old_path)
428 self.safe_remove(ABSTFN)
429 self.safe_remove(ABSTFN+"1")
430 self.safe_remove(ABSTFN+"2")
431
Tim Petersa45cacf2004-08-20 03:47:14 +0000432 def test_realpath_resolve_parents(self):
Johannes Gijsbers4ec40642004-08-14 15:01:53 +0000433 # We also need to resolve any symlinks in the parents of a relative
434 # path passed to realpath. E.g.: current working directory is
435 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
436 # realpath("a"). This should return /usr/share/doc/a/.
437 try:
438 old_path = abspath('.')
439 os.mkdir(ABSTFN)
440 os.mkdir(ABSTFN + "/y")
441 os.symlink(ABSTFN + "/y", ABSTFN + "/k")
442
443 os.chdir(ABSTFN + "/k")
444 self.assertEqual(realpath("a"), ABSTFN + "/y/a")
445 finally:
446 os.chdir(old_path)
447 self.safe_remove(ABSTFN + "/k")
448 self.safe_rmdir(ABSTFN + "/y")
449 self.safe_rmdir(ABSTFN)
450
451 def test_realpath_resolve_before_normalizing(self):
452 # Bug #990669: Symbolic links should be resolved before we
453 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
454 # in the following hierarchy:
455 # a/k/y
456 #
457 # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
458 # then realpath("link-y/..") should return 'k', not 'a'.
459 try:
460 old_path = abspath('.')
461 os.mkdir(ABSTFN)
462 os.mkdir(ABSTFN + "/k")
463 os.mkdir(ABSTFN + "/k/y")
464 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
465
466 # Absolute path.
467 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
468 # Relative path.
469 os.chdir(dirname(ABSTFN))
470 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."), ABSTFN + "/k")
471 finally:
472 os.chdir(old_path)
473 self.safe_remove(ABSTFN + "/link-y")
474 self.safe_rmdir(ABSTFN + "/k/y")
475 self.safe_rmdir(ABSTFN + "/k")
476 self.safe_rmdir(ABSTFN)
477
478 # Convenience functions for removing temporary files.
479 def pass_os_error(self, func, filename):
480 try: func(filename)
481 except OSError: pass
482
483 def safe_remove(self, filename):
484 self.pass_os_error(os.remove, filename)
485
486 def safe_rmdir(self, dirname):
487 self.pass_os_error(os.rmdir, dirname)
Brett Cannonb47243a2003-06-16 21:54:50 +0000488
489def test_main():
490 test_support.run_unittest(PosixPathTest)
491
492if __name__=="__main__":
493 test_main()