]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | # Test the Unicode versions of normal file functions\r |
2 | # open, os.open, os.stat. os.listdir, os.rename, os.remove, os.mkdir, os.chdir, os.rmdir\r | |
3 | import sys, os, unittest\r | |
4 | from unicodedata import normalize\r | |
5 | from test import test_support\r | |
6 | \r | |
7 | filenames = [\r | |
8 | '1_abc',\r | |
9 | u'2_ascii',\r | |
10 | u'3_Gr\xfc\xdf-Gott',\r | |
11 | u'4_\u0393\u03b5\u03b9\u03ac-\u03c3\u03b1\u03c2',\r | |
12 | u'5_\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435',\r | |
13 | u'6_\u306b\u307d\u3093',\r | |
14 | u'7_\u05d4\u05e9\u05e7\u05e6\u05e5\u05e1',\r | |
15 | u'8_\u66e8\u66e9\u66eb',\r | |
16 | u'9_\u66e8\u05e9\u3093\u0434\u0393\xdf',\r | |
17 | # Specific code points: fn, NFC(fn) and NFKC(fn) all differents\r | |
18 | u'10_\u1fee\u1ffd',\r | |
19 | ]\r | |
20 | \r | |
21 | # Mac OS X decomposes Unicode names, using Normal Form D.\r | |
22 | # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html\r | |
23 | # "However, most volume formats do not follow the exact specification for\r | |
24 | # these normal forms. For example, HFS Plus uses a variant of Normal Form D\r | |
25 | # in which U+2000 through U+2FFF, U+F900 through U+FAFF, and U+2F800 through\r | |
26 | # U+2FAFF are not decomposed."\r | |
27 | if sys.platform != 'darwin':\r | |
28 | filenames.extend([\r | |
29 | # Specific code points: NFC(fn), NFD(fn), NFKC(fn) and NFKD(fn) all differents\r | |
30 | u'11_\u0385\u03d3\u03d4',\r | |
31 | u'12_\u00a8\u0301\u03d2\u0301\u03d2\u0308', # == NFD(u'\u0385\u03d3\u03d4')\r | |
32 | u'13_\u0020\u0308\u0301\u038e\u03ab', # == NFKC(u'\u0385\u03d3\u03d4')\r | |
33 | u'14_\u1e9b\u1fc1\u1fcd\u1fce\u1fcf\u1fdd\u1fde\u1fdf\u1fed',\r | |
34 | \r | |
35 | # Specific code points: fn, NFC(fn) and NFKC(fn) all differents\r | |
36 | u'15_\u1fee\u1ffd\ufad1',\r | |
37 | u'16_\u2000\u2000\u2000A',\r | |
38 | u'17_\u2001\u2001\u2001A',\r | |
39 | u'18_\u2003\u2003\u2003A', # == NFC(u'\u2001\u2001\u2001A')\r | |
40 | u'19_\u0020\u0020\u0020A', # u'\u0020' == u' ' == NFKC(u'\u2000') ==\r | |
41 | # NFKC(u'\u2001') == NFKC(u'\u2003')\r | |
42 | ])\r | |
43 | \r | |
44 | \r | |
45 | # Is it Unicode-friendly?\r | |
46 | if not os.path.supports_unicode_filenames:\r | |
47 | fsencoding = sys.getfilesystemencoding() or sys.getdefaultencoding()\r | |
48 | try:\r | |
49 | for name in filenames:\r | |
50 | name.encode(fsencoding)\r | |
51 | except UnicodeEncodeError:\r | |
52 | raise unittest.SkipTest("only NT+ and systems with "\r | |
53 | "Unicode-friendly filesystem encoding")\r | |
54 | \r | |
55 | \r | |
56 | # Destroy directory dirname and all files under it, to one level.\r | |
57 | def deltree(dirname):\r | |
58 | # Don't hide legitimate errors: if one of these suckers exists, it's\r | |
59 | # an error if we can't remove it.\r | |
60 | if os.path.exists(dirname):\r | |
61 | # must pass unicode to os.listdir() so we get back unicode results.\r | |
62 | for fname in os.listdir(unicode(dirname)):\r | |
63 | os.unlink(os.path.join(dirname, fname))\r | |
64 | os.rmdir(dirname)\r | |
65 | \r | |
66 | \r | |
67 | class UnicodeFileTests(unittest.TestCase):\r | |
68 | files = set(filenames)\r | |
69 | normal_form = None\r | |
70 | \r | |
71 | def setUp(self):\r | |
72 | try:\r | |
73 | os.mkdir(test_support.TESTFN)\r | |
74 | except OSError:\r | |
75 | pass\r | |
76 | files = set()\r | |
77 | for name in self.files:\r | |
78 | name = os.path.join(test_support.TESTFN, self.norm(name))\r | |
79 | with open(name, 'w') as f:\r | |
80 | f.write((name+'\n').encode("utf-8"))\r | |
81 | os.stat(name)\r | |
82 | files.add(name)\r | |
83 | self.files = files\r | |
84 | \r | |
85 | def tearDown(self):\r | |
86 | deltree(test_support.TESTFN)\r | |
87 | \r | |
88 | def norm(self, s):\r | |
89 | if self.normal_form and isinstance(s, unicode):\r | |
90 | return normalize(self.normal_form, s)\r | |
91 | return s\r | |
92 | \r | |
93 | def _apply_failure(self, fn, filename, expected_exception,\r | |
94 | check_fn_in_exception = True):\r | |
95 | with self.assertRaises(expected_exception) as c:\r | |
96 | fn(filename)\r | |
97 | exc_filename = c.exception.filename\r | |
98 | # the "filename" exception attribute may be encoded\r | |
99 | if isinstance(exc_filename, str):\r | |
100 | filename = filename.encode(sys.getfilesystemencoding())\r | |
101 | if check_fn_in_exception:\r | |
102 | self.assertEqual(exc_filename, filename, "Function '%s(%r) failed "\r | |
103 | "with bad filename in the exception: %r" %\r | |
104 | (fn.__name__, filename, exc_filename))\r | |
105 | \r | |
106 | def test_failures(self):\r | |
107 | # Pass non-existing Unicode filenames all over the place.\r | |
108 | for name in self.files:\r | |
109 | name = "not_" + name\r | |
110 | self._apply_failure(open, name, IOError)\r | |
111 | self._apply_failure(os.stat, name, OSError)\r | |
112 | self._apply_failure(os.chdir, name, OSError)\r | |
113 | self._apply_failure(os.rmdir, name, OSError)\r | |
114 | self._apply_failure(os.remove, name, OSError)\r | |
115 | # listdir may append a wildcard to the filename, so dont check\r | |
116 | self._apply_failure(os.listdir, name, OSError, False)\r | |
117 | \r | |
118 | def test_open(self):\r | |
119 | for name in self.files:\r | |
120 | f = open(name, 'w')\r | |
121 | f.write((name+'\n').encode("utf-8"))\r | |
122 | f.close()\r | |
123 | os.stat(name)\r | |
124 | \r | |
125 | # Skip the test on darwin, because darwin does normalize the filename to\r | |
126 | # NFD (a variant of Unicode NFD form). Normalize the filename to NFC, NFKC,\r | |
127 | # NFKD in Python is useless, because darwin will normalize it later and so\r | |
128 | # open(), os.stat(), etc. don't raise any exception.\r | |
129 | @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')\r | |
130 | def test_normalize(self):\r | |
131 | files = set(f for f in self.files if isinstance(f, unicode))\r | |
132 | others = set()\r | |
133 | for nf in set(['NFC', 'NFD', 'NFKC', 'NFKD']):\r | |
134 | others |= set(normalize(nf, file) for file in files)\r | |
135 | others -= files\r | |
136 | for name in others:\r | |
137 | self._apply_failure(open, name, IOError)\r | |
138 | self._apply_failure(os.stat, name, OSError)\r | |
139 | self._apply_failure(os.chdir, name, OSError)\r | |
140 | self._apply_failure(os.rmdir, name, OSError)\r | |
141 | self._apply_failure(os.remove, name, OSError)\r | |
142 | # listdir may append a wildcard to the filename, so dont check\r | |
143 | self._apply_failure(os.listdir, name, OSError, False)\r | |
144 | \r | |
145 | # Skip the test on darwin, because darwin uses a normalization different\r | |
146 | # than Python NFD normalization: filenames are different even if we use\r | |
147 | # Python NFD normalization.\r | |
148 | @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')\r | |
149 | def test_listdir(self):\r | |
150 | sf0 = set(self.files)\r | |
151 | f1 = os.listdir(test_support.TESTFN)\r | |
152 | f2 = os.listdir(unicode(test_support.TESTFN,\r | |
153 | sys.getfilesystemencoding()))\r | |
154 | sf2 = set(os.path.join(unicode(test_support.TESTFN), f) for f in f2)\r | |
155 | self.assertEqual(sf0, sf2)\r | |
156 | self.assertEqual(len(f1), len(f2))\r | |
157 | \r | |
158 | def test_rename(self):\r | |
159 | for name in self.files:\r | |
160 | os.rename(name, "tmp")\r | |
161 | os.rename("tmp", name)\r | |
162 | \r | |
163 | def test_directory(self):\r | |
164 | dirname = os.path.join(test_support.TESTFN,\r | |
165 | u'Gr\xfc\xdf-\u66e8\u66e9\u66eb')\r | |
166 | filename = u'\xdf-\u66e8\u66e9\u66eb'\r | |
167 | oldwd = os.getcwd()\r | |
168 | os.mkdir(dirname)\r | |
169 | os.chdir(dirname)\r | |
170 | try:\r | |
171 | with open(filename, 'w') as f:\r | |
172 | f.write((filename + '\n').encode("utf-8"))\r | |
173 | os.access(filename,os.R_OK)\r | |
174 | os.remove(filename)\r | |
175 | finally:\r | |
176 | os.chdir(oldwd)\r | |
177 | os.rmdir(dirname)\r | |
178 | \r | |
179 | \r | |
180 | class UnicodeNFCFileTests(UnicodeFileTests):\r | |
181 | normal_form = 'NFC'\r | |
182 | \r | |
183 | \r | |
184 | class UnicodeNFDFileTests(UnicodeFileTests):\r | |
185 | normal_form = 'NFD'\r | |
186 | \r | |
187 | \r | |
188 | class UnicodeNFKCFileTests(UnicodeFileTests):\r | |
189 | normal_form = 'NFKC'\r | |
190 | \r | |
191 | \r | |
192 | class UnicodeNFKDFileTests(UnicodeFileTests):\r | |
193 | normal_form = 'NFKD'\r | |
194 | \r | |
195 | \r | |
196 | def test_main():\r | |
197 | try:\r | |
198 | test_support.run_unittest(\r | |
199 | UnicodeFileTests,\r | |
200 | UnicodeNFCFileTests,\r | |
201 | UnicodeNFDFileTests,\r | |
202 | UnicodeNFKCFileTests,\r | |
203 | UnicodeNFKDFileTests,\r | |
204 | )\r | |
205 | finally:\r | |
206 | deltree(test_support.TESTFN)\r | |
207 | \r | |
208 | \r | |
209 | if __name__ == "__main__":\r | |
210 | test_main()\r |