1 import unittest 2 from test import test_support, test_genericpath 3 4 import posixpath, os 5 from posixpath import realpath, abspath, 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 10 ABSTFN = abspath(test_support.TESTFN) 11 12 def safe_rmdir(dirname): 13 try: 14 os.rmdir(dirname) 15 except OSError: 16 pass 17 18 class PosixPathTest(unittest.TestCase): 19 20 def setUp(self): 21 self.tearDown() 22 23 def tearDown(self): 24 for suffix in ["", "1", "2"]: 25 test_support.unlink(test_support.TESTFN + suffix) 26 safe_rmdir(test_support.TESTFN + suffix) 27 28 def test_join(self): 29 self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"), "/bar/baz") 30 self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz") 31 self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"), "/foo/bar/baz/") 32 33 def test_split(self): 34 self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar")) 35 self.assertEqual(posixpath.split("/"), ("/", "")) 36 self.assertEqual(posixpath.split("foo"), ("", "foo")) 37 self.assertEqual(posixpath.split("////foo"), ("////", "foo")) 38 self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar")) 39 40 def splitextTest(self, path, filename, ext): 41 self.assertEqual(posixpath.splitext(path), (filename, ext)) 42 self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext)) 43 self.assertEqual(posixpath.splitext("abc/" + path), ("abc/" + filename, ext)) 44 self.assertEqual(posixpath.splitext("abc.def/" + path), ("abc.def/" + filename, ext)) 45 self.assertEqual(posixpath.splitext("/abc.def/" + path), ("/abc.def/" + filename, ext)) 46 self.assertEqual(posixpath.splitext(path + "/"), (filename + ext + "/", "")) 47 48 def test_splitext(self): 49 self.splitextTest("foo.bar", "foo", ".bar") 50 self.splitextTest("foo.boo.bar", "foo.boo", ".bar") 51 self.splitextTest("foo.boo.biff.bar", "foo.boo.biff", ".bar") 52 self.splitextTest(".csh.rc", ".csh", ".rc") 53 self.splitextTest("nodots", "nodots", "") 54 self.splitextTest(".cshrc", ".cshrc", "") 55 self.splitextTest("...manydots", "...manydots", "") 56 self.splitextTest("...manydots.ext", "...manydots", ".ext") 57 self.splitextTest(".", ".", "") 58 self.splitextTest("..", "..", "") 59 self.splitextTest("........", "........", "") 60 self.splitextTest("", "", "") 61 62 def test_isabs(self): 63 self.assertIs(posixpath.isabs(""), False) 64 self.assertIs(posixpath.isabs("/"), True) 65 self.assertIs(posixpath.isabs("/foo"), True) 66 self.assertIs(posixpath.isabs("/foo/bar"), True) 67 self.assertIs(posixpath.isabs("foo/bar"), False) 68 69 def test_basename(self): 70 self.assertEqual(posixpath.basename("/foo/bar"), "bar") 71 self.assertEqual(posixpath.basename("/"), "") 72 self.assertEqual(posixpath.basename("foo"), "foo") 73 self.assertEqual(posixpath.basename("////foo"), "foo") 74 self.assertEqual(posixpath.basename("//foo//bar"), "bar") 75 76 def test_dirname(self): 77 self.assertEqual(posixpath.dirname("/foo/bar"), "/foo") 78 self.assertEqual(posixpath.dirname("/"), "/") 79 self.assertEqual(posixpath.dirname("foo"), "") 80 self.assertEqual(posixpath.dirname("////foo"), "////") 81 self.assertEqual(posixpath.dirname("//foo//bar"), "//foo") 82 83 def test_islink(self): 84 self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False) 85 f = open(test_support.TESTFN + "1", "wb") 86 try: 87 f.write("foo") 88 f.close() 89 self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False) 90 if hasattr(os, "symlink"): 91 os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2") 92 self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True) 93 os.remove(test_support.TESTFN + "1") 94 self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True) 95 self.assertIs(posixpath.exists(test_support.TESTFN + "2"), False) 96 self.assertIs(posixpath.lexists(test_support.TESTFN + "2"), True) 97 finally: 98 if not f.close(): 99 f.close() 100 101 def test_samefile(self): 102 f = open(test_support.TESTFN + "1", "wb") 103 try: 104 f.write("foo") 105 f.close() 106 self.assertIs( 107 posixpath.samefile( 108 test_support.TESTFN + "1", 109 test_support.TESTFN + "1" 110 ), 111 True 112 ) 113 # If we don't have links, assume that os.stat doesn't return resonable 114 # inode information and thus, that samefile() doesn't work 115 if hasattr(os, "symlink"): 116 os.symlink( 117 test_support.TESTFN + "1", 118 test_support.TESTFN + "2" 119 ) 120 self.assertIs( 121 posixpath.samefile( 122 test_support.TESTFN + "1", 123 test_support.TESTFN + "2" 124 ), 125 True 126 ) 127 os.remove(test_support.TESTFN + "2") 128 f = open(test_support.TESTFN + "2", "wb") 129 f.write("bar") 130 f.close() 131 self.assertIs( 132 posixpath.samefile( 133 test_support.TESTFN + "1", 134 test_support.TESTFN + "2" 135 ), 136 False 137 ) 138 finally: 139 if not f.close(): 140 f.close() 141 142 def test_samestat(self): 143 f = open(test_support.TESTFN + "1", "wb") 144 try: 145 f.write("foo") 146 f.close() 147 self.assertIs( 148 posixpath.samestat( 149 os.stat(test_support.TESTFN + "1"), 150 os.stat(test_support.TESTFN + "1") 151 ), 152 True 153 ) 154 # If we don't have links, assume that os.stat() doesn't return resonable 155 # inode information and thus, that samefile() doesn't work 156 if hasattr(os, "symlink"): 157 if hasattr(os, "symlink"): 158 os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2") 159 self.assertIs( 160 posixpath.samestat( 161 os.stat(test_support.TESTFN + "1"), 162 os.stat(test_support.TESTFN + "2") 163 ), 164 True 165 ) 166 os.remove(test_support.TESTFN + "2") 167 f = open(test_support.TESTFN + "2", "wb") 168 f.write("bar") 169 f.close() 170 self.assertIs( 171 posixpath.samestat( 172 os.stat(test_support.TESTFN + "1"), 173 os.stat(test_support.TESTFN + "2") 174 ), 175 False 176 ) 177 finally: 178 if not f.close(): 179 f.close() 180 181 def test_ismount(self): 182 self.assertIs(posixpath.ismount("/"), True) 183 184 def test_expanduser(self): 185 self.assertEqual(posixpath.expanduser("foo"), "foo") 186 try: 187 import pwd 188 except ImportError: 189 pass 190 else: 191 self.assertIsInstance(posixpath.expanduser("~/"), basestring) 192 # if home directory == root directory, this test makes no sense 193 if posixpath.expanduser("~") != '/': 194 self.assertEqual( 195 posixpath.expanduser("~") + "/", 196 posixpath.expanduser("~/") 197 ) 198 self.assertIsInstance(posixpath.expanduser("~root/"), basestring) 199 self.assertIsInstance(posixpath.expanduser("~foo/"), basestring) 200 201 with test_support.EnvironmentVarGuard() as env: 202 env['HOME'] = '/' 203 self.assertEqual(posixpath.expanduser("~"), "/") 204 205 def test_normpath(self): 206 self.assertEqual(posixpath.normpath(""), ".") 207 self.assertEqual(posixpath.normpath("/"), "/") 208 self.assertEqual(posixpath.normpath("//"), "//") 209 self.assertEqual(posixpath.normpath("///"), "/") 210 self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar") 211 self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"), "/foo/baz") 212 self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar") 213 214 if hasattr(os, "symlink"): 215 def test_realpath_basic(self): 216 # Basic operation. 217 try: 218 os.symlink(ABSTFN+"1", ABSTFN) 219 self.assertEqual(realpath(ABSTFN), ABSTFN+"1") 220 finally: 221 test_support.unlink(ABSTFN) 222 223 def test_realpath_symlink_loops(self): 224 # Bug #930024, return the path unchanged if we get into an infinite 225 # symlink loop. 226 try: 227 old_path = abspath('.') 228 os.symlink(ABSTFN, ABSTFN) 229 self.assertEqual(realpath(ABSTFN), ABSTFN) 230 231 os.symlink(ABSTFN+"1", ABSTFN+"2") 232 os.symlink(ABSTFN+"2", ABSTFN+"1") 233 self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1") 234 self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2") 235 236 # Test using relative path as well. 237 os.chdir(dirname(ABSTFN)) 238 self.assertEqual(realpath(basename(ABSTFN)), ABSTFN) 239 finally: 240 os.chdir(old_path) 241 test_support.unlink(ABSTFN) 242 test_support.unlink(ABSTFN+"1") 243 test_support.unlink(ABSTFN+"2") 244 245 def test_realpath_resolve_parents(self): 246 # We also need to resolve any symlinks in the parents of a relative 247 # path passed to realpath. E.g.: current working directory is 248 # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call 249 # realpath("a"). This should return /usr/share/doc/a/. 250 try: 251 old_path = abspath('.') 252 os.mkdir(ABSTFN) 253 os.mkdir(ABSTFN + "/y") 254 os.symlink(ABSTFN + "/y", ABSTFN + "/k") 255 256 os.chdir(ABSTFN + "/k") 257 self.assertEqual(realpath("a"), ABSTFN + "/y/a") 258 finally: 259 os.chdir(old_path) 260 test_support.unlink(ABSTFN + "/k") 261 safe_rmdir(ABSTFN + "/y") 262 safe_rmdir(ABSTFN) 263 264 def test_realpath_resolve_before_normalizing(self): 265 # Bug #990669: Symbolic links should be resolved before we 266 # normalize the path. E.g.: if we have directories 'a', 'k' and 'y' 267 # in the following hierarchy: 268 # a/k/y 269 # 270 # and a symbolic link 'link-y' pointing to 'y' in directory 'a', 271 # then realpath("link-y/..") should return 'k', not 'a'. 272 try: 273 old_path = abspath('.') 274 os.mkdir(ABSTFN) 275 os.mkdir(ABSTFN + "/k") 276 os.mkdir(ABSTFN + "/k/y") 277 os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y") 278 279 # Absolute path. 280 self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k") 281 # Relative path. 282 os.chdir(dirname(ABSTFN)) 283 self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."), 284 ABSTFN + "/k") 285 finally: 286 os.chdir(old_path) 287 test_support.unlink(ABSTFN + "/link-y") 288 safe_rmdir(ABSTFN + "/k/y") 289 safe_rmdir(ABSTFN + "/k") 290 safe_rmdir(ABSTFN) 291 292 def test_realpath_resolve_first(self): 293 # Bug #1213894: The first component of the path, if not absolute, 294 # must be resolved too. 295 296 try: 297 old_path = abspath('.') 298 os.mkdir(ABSTFN) 299 os.mkdir(ABSTFN + "/k") 300 os.symlink(ABSTFN, ABSTFN + "link") 301 os.chdir(dirname(ABSTFN)) 302 303 base = basename(ABSTFN) 304 self.assertEqual(realpath(base + "link"), ABSTFN) 305 self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k") 306 finally: 307 os.chdir(old_path) 308 test_support.unlink(ABSTFN + "link") 309 safe_rmdir(ABSTFN + "/k") 310 safe_rmdir(ABSTFN) 311 312 def test_relpath(self): 313 (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar") 314 try: 315 curdir = os.path.split(os.getcwd())[-1] 316 self.assertRaises(ValueError, posixpath.relpath, "") 317 self.assertEqual(posixpath.relpath("a"), "a") 318 self.assertEqual(posixpath.relpath(posixpath.abspath("a")), "a") 319 self.assertEqual(posixpath.relpath("a/b"), "a/b") 320 self.assertEqual(posixpath.relpath("../a/b"), "../a/b") 321 self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a") 322 self.assertEqual(posixpath.relpath("a/b", "../c"), "../"+curdir+"/a/b") 323 self.assertEqual(posixpath.relpath("a", "b/c"), "../../a") 324 self.assertEqual(posixpath.relpath("a", "a"), ".") 325 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x/y/z"), '../../../foo/bar/bat') 326 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/foo/bar"), 'bat') 327 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/"), 'foo/bar/bat') 328 self.assertEqual(posixpath.relpath("/", "/foo/bar/bat"), '../../..') 329 self.assertEqual(posixpath.relpath("/foo/bar/bat", "/x"), '../foo/bar/bat') 330 self.assertEqual(posixpath.relpath("/x", "/foo/bar/bat"), '../../../x') 331 self.assertEqual(posixpath.relpath("/", "/"), '.') 332 self.assertEqual(posixpath.relpath("/a", "/a"), '.') 333 self.assertEqual(posixpath.relpath("/a/b", "/a/b"), '.') 334 finally: 335 os.getcwd = real_getcwd 336 337 338 class PosixCommonTest(test_genericpath.CommonTest): 339 pathmodule = posixpath 340 attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat'] 341 342 343 def test_main(): 344 test_support.run_unittest(PosixPathTest, PosixCommonTest) 345 346 347 if __name__=="__main__": 348 test_main() 349