MCPcopy Index your code
hub / github.com/python/cpython / ToUnicode

Function ToUnicode

Lib/encodings/idna.py:117–174  ·  view source on GitHub ↗
(label)

Source from the content-addressed store, hash-verified

115 raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
116
117def ToUnicode(label):
118 if len(label) > 1024:
119 # Protection from https://github.com/python/cpython/issues/98433.
120 # https://datatracker.ietf.org/doc/html/rfc5894#section-6
121 # doesn't specify a label size limit prior to NAMEPREP. But having
122 # one makes practical sense.
123 # This leaves ample room for nameprep() to remove Nothing characters
124 # per https://www.rfc-editor.org/rfc/rfc3454#section-3.1 while still
125 # preventing us from wasting time decoding a big thing that'll just
126 # hit the actual <= 63 length limit in Step 6.
127 if isinstance(label, str):
128 label = label.encode("utf-8", errors="backslashreplace")
129 raise UnicodeDecodeError("idna", label, 0, len(label), "label way too long")
130 # Step 1: Check for ASCII
131 if isinstance(label, bytes):
132 pure_ascii = True
133 else:
134 try:
135 label = label.encode("ascii")
136 pure_ascii = True
137 except UnicodeEncodeError:
138 pure_ascii = False
139 if not pure_ascii:
140 assert isinstance(label, str)
141 # Step 2: Perform nameprep
142 label = nameprep(label)
143 # It doesn't say this, but apparently, it should be ASCII now
144 try:
145 label = label.encode("ascii")
146 except UnicodeEncodeError as exc:
147 raise UnicodeEncodeError("idna", label, exc.start, exc.end,
148 "Invalid character in IDN label")
149 # Step 3: Check for ACE prefix
150 assert isinstance(label, bytes)
151 if not label.lower().startswith(ace_prefix):
152 return str(label, "ascii")
153
154 # Step 4: Remove ACE prefix
155 label1 = label[len(ace_prefix):]
156
157 # Step 5: Decode using PUNYCODE
158 try:
159 result = label1.decode("punycode")
160 except UnicodeDecodeError as exc:
161 offset = len(ace_prefix)
162 raise UnicodeDecodeError("idna", label, offset+exc.start, offset+exc.end, exc.reason)
163
164 # Step 6: Apply ToASCII
165 label2 = ToASCII(result)
166
167 # Step 7: Compare the result of step 6 with the one of step 3
168 # label2 will already be in lower case.
169 if str(label, "ascii").lower() != str(label2, "ascii"):
170 raise UnicodeDecodeError("idna", label, 0, len(label),
171 f"IDNA does not round-trip, '{label!r}' != '{label2!r}'")
172
173 # Step 8: return the result of step 5
174 return result

Callers 2

decodeMethod · 0.85
_buffer_decodeMethod · 0.85

Calls 7

nameprepFunction · 0.85
strFunction · 0.85
ToASCIIFunction · 0.85
encodeMethod · 0.45
startswithMethod · 0.45
lowerMethod · 0.45
decodeMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…