blob: e4709a189aa881d2435d56591ba629978ad01f02 [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
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +03008from test.support import (run_unittest, rmtree, change_cwd,
Victor Stinnerbf816222011-06-30 23:25:47 +02009 TESTFN_ENCODING, TESTFN_UNICODE, TESTFN_UNENCODABLE, create_empty_file)
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")
Florent Xiclunaca6befb2011-11-07 19:49:07 +010059 self.assertFalse(os.path.isfile(filename2))
60 self.assertTrue(os.path.isfile(filename1 + '.new'))
Mark Hammond6d459722003-12-03 01:29:56 +000061 os.rename(filename1 + ".new", filename2)
Florent Xiclunaca6befb2011-11-07 19:49:07 +010062 self.assertFalse(os.path.isfile(filename1 + '.new'))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000063 self.assertTrue(os.path.isfile(filename2))
Mark Hammondef8b6542001-05-13 08:04:26 +000064
Christian Heimese25f35e2008-03-20 10:49:03 +000065 shutil.copy(filename1, filename2 + ".new")
66 os.unlink(filename1 + ".new") # remove using equiv name.
67 # And a couple of moves, one using each name.
68 shutil.move(filename1, filename2 + ".new")
Florent Xiclunaca6befb2011-11-07 19:49:07 +010069 self.assertFalse(os.path.exists(filename2))
70 self.assertTrue(os.path.exists(filename1 + '.new'))
Christian Heimese25f35e2008-03-20 10:49:03 +000071 shutil.move(filename1 + ".new", filename2)
Florent Xiclunaca6befb2011-11-07 19:49:07 +010072 self.assertFalse(os.path.exists(filename2 + '.new'))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000073 self.assertTrue(os.path.exists(filename1))
Christian Heimese25f35e2008-03-20 10:49:03 +000074 # Note - due to the implementation of shutil.move,
75 # it tries a rename first. This only fails on Windows when on
76 # different file systems - and this test can't ensure that.
77 # So we test the shutil.copy2 function, which is the thing most
78 # likely to fail.
79 shutil.copy2(filename1, filename2 + ".new")
Florent Xiclunaca6befb2011-11-07 19:49:07 +010080 self.assertTrue(os.path.isfile(filename1 + '.new'))
Christian Heimese25f35e2008-03-20 10:49:03 +000081 os.unlink(filename1 + ".new")
Florent Xiclunaca6befb2011-11-07 19:49:07 +010082 self.assertFalse(os.path.exists(filename2 + '.new'))
Mark Hammondef8b6542001-05-13 08:04:26 +000083
Victor Stinnerca6525a2010-09-11 12:52:30 +000084 def _do_directory(self, make_name, chdir_name):
Mark Hammond6d459722003-12-03 01:29:56 +000085 if os.path.isdir(make_name):
Amaury Forgeot d'Arc84e17152008-10-03 19:34:30 +000086 rmtree(make_name)
Mark Hammond6d459722003-12-03 01:29:56 +000087 os.mkdir(make_name)
88 try:
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +030089 with change_cwd(chdir_name):
Victor Stinnerca6525a2010-09-11 12:52:30 +000090 cwd_result = os.getcwd()
91 name_result = make_name
Nicholas Bastin66803412004-03-21 20:55:47 +000092
93 cwd_result = unicodedata.normalize("NFD", cwd_result)
94 name_result = unicodedata.normalize("NFD", name_result)
95
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000096 self.assertEqual(os.path.basename(cwd_result),name_result)
Mark Hammond6d459722003-12-03 01:29:56 +000097 finally:
98 os.rmdir(make_name)
Mark Hammondef8b6542001-05-13 08:04:26 +000099
Mark Hammond6d459722003-12-03 01:29:56 +0000100 # The '_test' functions 'entry points with params' - ie, what the
101 # top-level 'test' functions would be if they could take params
102 def _test_single(self, filename):
103 remove_if_exists(filename)
Victor Stinnerbf816222011-06-30 23:25:47 +0200104 create_empty_file(filename)
Mark Hammond6d459722003-12-03 01:29:56 +0000105 try:
106 self._do_single(filename)
107 finally:
108 os.unlink(filename)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000109 self.assertTrue(not os.path.exists(filename))
Mark Hammond6d459722003-12-03 01:29:56 +0000110 # and again with os.open.
111 f = os.open(filename, os.O_CREAT)
112 os.close(f)
113 try:
114 self._do_single(filename)
115 finally:
116 os.unlink(filename)
Tim Peters58eb11c2004-01-18 20:29:55 +0000117
Mark Hammond6d459722003-12-03 01:29:56 +0000118 # The 'test' functions are unittest entry points, and simply call our
119 # _test functions with each of the filename combinations we wish to test
120 def test_single_files(self):
Mark Hammond6d459722003-12-03 01:29:56 +0000121 self._test_single(TESTFN_UNICODE)
Victor Stinner09c449c2010-08-13 22:23:24 +0000122 if TESTFN_UNENCODABLE is not None:
123 self._test_single(TESTFN_UNENCODABLE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000124
Mark Hammond6d459722003-12-03 01:29:56 +0000125 def test_directories(self):
Christian Heimese25f35e2008-03-20 10:49:03 +0000126 # For all 'equivalent' combinations:
127 # Make dir with encoded, chdir with unicode, checkdir with encoded
128 # (or unicode/encoded/unicode, etc
Martin v. Löwisa79f1252007-08-30 10:08:57 +0000129 ext = ".dir"
Victor Stinnerca6525a2010-09-11 12:52:30 +0000130 self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext)
Mark Hammond6d459722003-12-03 01:29:56 +0000131 # Our directory name that can't use a non-unicode name.
Victor Stinner09c449c2010-08-13 22:23:24 +0000132 if TESTFN_UNENCODABLE is not None:
133 self._do_directory(TESTFN_UNENCODABLE+ext,
Victor Stinnerca6525a2010-09-11 12:52:30 +0000134 TESTFN_UNENCODABLE+ext)
Mark Hammondef8b6542001-05-13 08:04:26 +0000135
Mark Hammond6d459722003-12-03 01:29:56 +0000136def test_main():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000137 run_unittest(__name__)
Mark Hammondef8b6542001-05-13 08:04:26 +0000138
Mark Hammond6d459722003-12-03 01:29:56 +0000139if __name__ == "__main__":
140 test_main()