11import re
2- from unicodedata import ucd_3_2_0 as unicodedata
2+ import unicodedata as unicodedata_current
3+ from unicodedata import ucd_3_2_0 as unicodedata_320
34
45def gen_category (cats ):
56 for i in range (0 , 0x110000 ):
6- if unicodedata .category (chr (i )) in cats :
7- yield ( i )
7+ if unicodedata_320 .category (chr (i )) in cats :
8+ yield i
89
910def gen_bidirectional (cats ):
1011 for i in range (0 , 0x110000 ):
11- if unicodedata .bidirectional (chr (i )) in cats :
12- yield ( i )
12+ if unicodedata_320 .bidirectional (chr (i )) in cats :
13+ yield i
1314
1415def compact_set (l ):
1516 single = []
@@ -116,10 +117,18 @@ def compact_set(l):
116117and mappings, for which a mapping function is provided.
117118\" \" \"
118119
119- from unicodedata import ucd_3_2_0 as unicodedata
120+ # This check asserts that mkstringprep.py has been run
121+ # when unicodedata is modified to ensure conformant behavior.
122+ import unicodedata
120123""" )
121124
122- print ("assert unicodedata.unidata_version == %r" % (unicodedata .unidata_version ,))
125+ print ("assert unicodedata.unidata_version == %r" % (unicodedata_current .unidata_version ,))
126+
127+ print ("""
128+ from unicodedata import ucd_3_2_0 as unicodedata_320
129+ """ )
130+
131+ print ("assert unicodedata_320.unidata_version == %r" % (unicodedata_320 .unidata_version ,))
123132
124133# A.1 is the table of unassigned characters
125134# XXX Plane 15 PUA is listed as unassigned in Python.
@@ -139,7 +148,7 @@ def compact_set(l):
139148
140149print ("""
141150def in_table_a1(code):
142- if unicodedata .category(code) != 'Cn': return False
151+ if unicodedata_320 .category(code) != 'Cn': return False
143152 c = ord(code)
144153 if 0xFDD0 <= c < 0xFDF0: return False
145154 return (c & 0xFFFF) not in (0xFFFE, 0xFFFF)
@@ -172,21 +181,33 @@ def in_table_b1(code):
172181
173182# B.3 is mostly Python's .lower, except for a number
174183# of special cases, e.g. considering canonical forms.
184+ # To enforce Unicode 3.2.0 behavior of .lower instead of
185+ # whatever Unicode version is included with Python we
186+ # add unassigned or newly case-folding codepoints to
187+ # the exception map, too.
175188
176189b3_exceptions = {}
177190
178191for k ,v in table_b2 .items ():
179192 if list (map (ord , chr (k ).lower ())) != v :
180193 b3_exceptions [k ] = "" .join (map (chr ,v ))
194+ for cp in range (0x110000 ):
195+ ch = chr (cp )
196+ # Assigned in current Unicode version
197+ # and supports case folding, but not
198+ # explicitly in B.2 or B.3 tables.
199+ if (unicodedata_current .category (ch ) != "Cn"
200+ and ch .lower () != ch
201+ and cp not in table_b2
202+ and cp not in table_b3 ):
203+ b3_exceptions [cp ] = ch # Identity.
181204
182205b3 = sorted (b3_exceptions .items ())
183206
184207print ("""
185208b3_exceptions = {""" )
186209for i , kv in enumerate (b3 ):
187- print ("0x%x:%a," % kv , end = ' ' )
188- if i % 4 == 3 :
189- print ()
210+ print ("0x%x:%a," % kv , end = '\n ' if i % 4 == 3 else ' ' )
190211print ("}" )
191212
192213print ("""
@@ -207,9 +228,9 @@ def map_table_b3(code):
207228
208229def map_table_b2 (a ):
209230 al = map_table_b3 (a )
210- b = unicodedata .normalize ("NFKC" , al )
231+ b = unicodedata_320 .normalize ("NFKC" , al )
211232 bl = "" .join ([map_table_b3 (ch ) for ch in b ])
212- c = unicodedata .normalize ("NFKC" , bl )
233+ c = unicodedata_320 .normalize ("NFKC" , bl )
213234 if b != c :
214235 return c
215236 else :
@@ -226,9 +247,9 @@ def map_table_b2(a):
226247print ("""
227248def map_table_b2(a):
228249 al = map_table_b3(a)
229- b = unicodedata .normalize("NFKC", al)
250+ b = unicodedata_320 .normalize("NFKC", al)
230251 bl = "".join([map_table_b3(ch) for ch in b])
231- c = unicodedata .normalize("NFKC", bl)
252+ c = unicodedata_320 .normalize("NFKC", bl)
232253 if b != c:
233254 return c
234255 else:
@@ -251,16 +272,16 @@ def in_table_c11(code):
251272del tables [0 ]
252273assert name == "C.1.2"
253274
254- # table = set(table.keys())
255- # Zs = set(gen_category(["Zs"])) - {0x20}
256- # assert Zs == table
275+ table = set (table .keys ())
276+ Zs = set (gen_category (["Zs" ])) - {0x20 }
277+ assert Zs == table
257278
258279print ("""
259280def in_table_c12(code):
260- return unicodedata .category(code) == "Zs" and code != " "
281+ return unicodedata_320 .category(code) == "Zs" and code != " "
261282
262283def in_table_c11_c12(code):
263- return unicodedata .category(code) == "Zs"
284+ return unicodedata_320 .category(code) == "Zs"
264285""" )
265286
266287# C.2.1 ASCII control characters
@@ -275,7 +296,7 @@ def in_table_c11_c12(code):
275296
276297print ("""
277298def in_table_c21(code):
278- return ord(code) < 128 and unicodedata .category(code) == "Cc"
299+ return ord(code) < 128 and unicodedata_320 .category(code) == "Cc"
279300""" )
280301
281302# C.2.2 Non-ASCII control characters. It also includes
@@ -295,11 +316,11 @@ def in_table_c21(code):
295316def in_table_c22(code):
296317 c = ord(code)
297318 if c < 128: return False
298- if unicodedata .category(code) == "Cc": return True
319+ if unicodedata_320 .category(code) == "Cc": return True
299320 return c in c22_specials
300321
301322def in_table_c21_c22(code):
302- return unicodedata .category(code) == "Cc" or \\
323+ return unicodedata_320 .category(code) == "Cc" or \\
303324 ord(code) in c22_specials
304325""" )
305326
@@ -313,7 +334,7 @@ def in_table_c21_c22(code):
313334
314335print ("""
315336def in_table_c3(code):
316- return unicodedata .category(code) == "Co"
337+ return unicodedata_320 .category(code) == "Co"
317338""" )
318339
319340# C.4 Non-character code points, xFFFE, xFFFF
@@ -346,7 +367,7 @@ def in_table_c4(code):
346367
347368print ("""
348369def in_table_c5(code):
349- return unicodedata .category(code) == "Cs"
370+ return unicodedata_320 .category(code) == "Cs"
350371""" )
351372
352373# C.6 Inappropriate for plain text
@@ -411,7 +432,7 @@ def in_table_c9(code):
411432
412433print ("""
413434def in_table_d1(code):
414- return unicodedata .bidirectional(code) in ("R","AL")
435+ return unicodedata_320 .bidirectional(code) in ("R","AL")
415436""" )
416437
417438# D.2 Characters with bidirectional property "L"
@@ -424,5 +445,5 @@ def in_table_d1(code):
424445
425446print ("""
426447def in_table_d2(code):
427- return unicodedata .bidirectional(code) == "L"
448+ return unicodedata_320 .bidirectional(code) == "L"
428449""" )
0 commit comments