blob: 6c2011ace8e1370bf36129a34bffa6f9fc57b4ed [file] [log] [blame]
Mark Hammondef8b6542001-05-13 08:04:26 +00001# Test some Unicode file name semantics
2# We dont test many operations on files other than
3# that their names can be used with Unicode characters.
Mark Hammond6d459722003-12-03 01:29:56 +00004import os, glob, time, shutil
Nicholas Bastin66803412004-03-21 20:55:47 +00005import unicodedata
Mark Hammondef8b6542001-05-13 08:04:26 +00006
Mark Hammond6d459722003-12-03 01:29:56 +00007import unittest
Victor Stinner3d85a6f2010-08-13 13:02:04 +00008from test.support import (run_unittest, rmtree,
Victor Stinner09c449c2010-08-13 22:23:24 +00009 TESTFN_ENCODING, TESTFN_UNICODE, TESTFN_UNENCODABLE)
Victor Stinner3d85a6f2010-08-13 13:02:04 +000010
Victor Stinnerca6525a2010-09-11 12:52:30 +000011if not os.path.supports_unicode_filenames:
12 try:
13 TESTFN_UNICODE.encode(TESTFN_ENCODING)
14 except (UnicodeError, TypeError):
15 # Either the file system encoding is None, or the file name
16 # cannot be encoded in the file system encoding.
17 raise unittest.SkipTest("No Unicode filesystem semantics on this platform.")
Mark Hammondef8b6542001-05-13 08:04:26 +000018
Mark Hammond6d459722003-12-03 01:29:56 +000019def remove_if_exists(filename):
20 if os.path.exists(filename):
21 os.unlink(filename)
Mark Hammondef8b6542001-05-13 08:04:26 +000022
Mark Hammond6d459722003-12-03 01:29:56 +000023class TestUnicodeFiles(unittest.TestCase):
24 # The 'do_' functions are the actual tests. They generally assume the
25 # file already exists etc.
Tim Peters58eb11c2004-01-18 20:29:55 +000026
Mark Hammond6d459722003-12-03 01:29:56 +000027 # Do all the tests we can given only a single filename. The file should
28 # exist.
29 def _do_single(self, filename):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000030 self.assertTrue(os.path.exists(filename))
31 self.assertTrue(os.path.isfile(filename))
32 self.assertTrue(os.access(filename, os.R_OK))
33 self.assertTrue(os.path.exists(os.path.abspath(filename)))
34 self.assertTrue(os.path.isfile(os.path.abspath(filename)))
35 self.assertTrue(os.access(os.path.abspath(filename), os.R_OK))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000036 os.chmod(filename, 0o777)
Mark Hammond6d459722003-12-03 01:29:56 +000037 os.utime(filename, None)
38 os.utime(filename, (time.time(), time.time()))
39 # Copy/rename etc tests using the same filename
40 self._do_copyish(filename, filename)
41 # Filename should appear in glob output
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000042 self.assertTrue(
Mark Hammond6d459722003-12-03 01:29:56 +000043 os.path.abspath(filename)==os.path.abspath(glob.glob(filename)[0]))
44 # basename should appear in listdir.
45 path, base = os.path.split(os.path.abspath(filename))
Raymond Hettinger3b04ce82004-06-28 06:57:19 +000046 file_list = os.listdir(path)
Raymond Hettinger3b04ce82004-06-28 06:57:19 +000047 # Normalize the unicode strings, as round-tripping the name via the OS
48 # may return a different (but equivalent) value.
49 base = unicodedata.normalize("NFD", base)
Nicholas Bastin66803412004-03-21 20:55:47 +000050 file_list = [unicodedata.normalize("NFD", f) for f in file_list]
51
Benjamin Peterson577473f2010-01-19 00:09:57 +000052 self.assertIn(base, file_list)
Tim Peters58eb11c2004-01-18 20:29:55 +000053
Mark Hammond6d459722003-12-03 01:29:56 +000054 # Tests that copy, move, etc one file to another.
55 def _do_copyish(self, filename1, filename2):
56 # Should be able to rename the file using either name.
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000057 self.assertTrue(os.path.isfile(filename1)) # must exist.
Mark Hammond6d459722003-12-03 01:29:56 +000058 os.rename(filename1, filename2 + ".new")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000059 self.assertTrue(os.path.isfile(filename1+".new"))
Mark Hammond6d459722003-12-03 01:29:56 +000060 os.rename(filename1 + ".new", filename2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000061 self.assertTrue(os.path.isfile(filename2))
Mark Hammondef8b6542001-05-13 08:04:26 +000062
Christian Heimese25f35e2008-03-20 10:49:03 +000063 shutil.copy(filename1, filename2 + ".new")
64 os.unlink(filename1 + ".new") # remove using equiv name.
65 # And a couple of moves, one using each name.
66 shutil.move(filename1, filename2 + ".new")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000067 self.assertTrue(not os.path.exists(filename2))
Christian Heimese25f35e2008-03-20 10:49:03 +000068 shutil.move(filename1 + ".new", filename2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000069 self.assertTrue(os.path.exists(filename1))
Christian Heimese25f35e2008-03-20 10:49:03 +000070 # Note - due to the implementation of shutil.move,
71 # it tries a rename first. This only fails on Windows when on
72 # different file systems - and this test can't ensure that.
73 # So we test the shutil.copy2 function, which is the thing most
74 # likely to fail.
75 shutil.copy2(filename1, filename2 + ".new")
76 os.unlink(filename1 + ".new")
Mark Hammondef8b6542001-05-13 08:04:26 +000077
Victor Stinnerca6525a2010-09-11 12:52:30 +000078 def _do_directory(self, make_name, chdir_name):
Guido van Rossumf0af3e32008-10-02 18:55:37 +000079 cwd = os.getcwdb()
Mark Hammond6d459722003-12-03 01:29:56 +000080 if os.path.isdir(make_name):
Amaury Forgeot d'Arc84e17152008-10-03 19:34:30 +000081 rmtree(make_name)
Mark Hammond6d459722003-12-03 01:29:56 +000082 os.mkdir(make_name)
83 try:
84 os.chdir(chdir_name)
85 try:
Victor Stinnerca6525a2010-09-11 12:52:30 +000086 cwd_result = os.getcwd()
87 name_result = make_name
Nicholas Bastin66803412004-03-21 20:55:47 +000088
89 cwd_result = unicodedata.normalize("NFD", cwd_result)
90 name_result = unicodedata.normalize("NFD", name_result)
91
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000092 self.assertEqual(os.path.basename(cwd_result),name_result)
Mark Hammond6d459722003-12-03 01:29:56 +000093 finally:
94 os.chdir(cwd)
95 finally:
96 os.rmdir(make_name)
Mark Hammondef8b6542001-05-13 08:04:26 +000097
Mark Hammond6d459722003-12-03 01:29:56 +000098 # The '_test' functions 'entry points with params' - ie, what the
99 # top-level 'test' functions would be if they could take params
100 def _test_single(self, filename):
101 remove_if_exists(filename)
Alex Martelli01c77c62006-08-24 02:58:11 +0000102 f = open(filename, "w")
Mark Hammond6d459722003-12-03 01:29:56 +0000103 f.close()
104 try:
105 self._do_single(filename)
106 finally:
107 os.unlink(filename)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000108 self.assertTrue(not os.path.exists(filename))
Mark Hammond6d459722003-12-03 01:29:56 +0000109 # and again with os.open.
110 f = os.open(filename, os.O_CREAT)
111 os.close(f)
112 try:
113 self._do_single(filename)
114 finally:
115 os.unlink(filename)
Tim Peters58eb11c2004-01-18 20:29:55 +0000116
Mark Hammond6d459722003-12-03 01:29:56 +0000117 # The 'test' functions are unittest entry points, and simply call our
118 # _test functions with each of the filename combinations we wish to test
119 def test_single_files(self):
Mark Hammond6d459722003-12-03 01:29:56 +0000120 self._test_single(TESTFN_UNICODE)
Victor Stinner09c449c2010-08-13 22:23:24 +0000121 if TESTFN_UNENCODABLE is not None:
122 self._test_single(TESTFN_UNENCODABLE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000123
Mark Hammond6d459722003-12-03 01:29:56 +0000124 def test_directories(self):
Christian Heimese25f35e2008-03-20 10:49:03 +0000125 # For all 'equivalent' combinations:
126 # Make dir with encoded, chdir with unicode, checkdir with encoded
127 # (or unicode/encoded/unicode, etc
Martin v. Löwisa79f1252007-08-30 10:08:57 +0000128 ext = ".dir"
Victor Stinnerca6525a2010-09-11 12:52:30 +0000129 self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext)
Mark Hammond6d459722003-12-03 01:29:56 +0000130 # Our directory name that can't use a non-unicode name.
Victor Stinner09c449c2010-08-13 22:23:24 +0000131 if TESTFN_UNENCODABLE is not None:
132 self._do_directory(TESTFN_UNENCODABLE+ext,
Victor Stinnerca6525a2010-09-11 12:52:30 +0000133 TESTFN_UNENCODABLE+ext)
Mark Hammondef8b6542001-05-13 08:04:26 +0000134
Mark Hammond6d459722003-12-03 01:29:56 +0000135def test_main():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000136 run_unittest(__name__)
Mark Hammondef8b6542001-05-13 08:04:26 +0000137
Mark Hammond6d459722003-12-03 01:29:56 +0000138if __name__ == "__main__":
139 test_main()