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