|
84 | 84 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
|
85 | 85 |
|
86 | 86 | import java.math.BigInteger;
|
| 87 | +import java.nio.charset.Charset; |
| 88 | +import java.nio.charset.CodingErrorAction; |
| 89 | +import java.nio.charset.StandardCharsets; |
87 | 90 | import java.util.Arrays;
|
88 | 91 | import java.util.List;
|
89 | 92 | import java.util.Locale;
|
|
160 | 163 | import com.oracle.graal.python.nodes.BuiltinNames;
|
161 | 164 | import com.oracle.graal.python.nodes.ErrorMessages;
|
162 | 165 | import com.oracle.graal.python.nodes.PGuards;
|
| 166 | +import com.oracle.graal.python.nodes.SpecialAttributeNames; |
163 | 167 | import com.oracle.graal.python.nodes.SpecialMethodNames;
|
164 | 168 | import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
|
165 | 169 | import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetAnyAttributeNode;
|
@@ -2309,6 +2313,22 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
|
2309 | 2313 | } else {
|
2310 | 2314 | pythonClass.setAttribute(key, value);
|
2311 | 2315 | }
|
| 2316 | + } else if (SpecialAttributeNames.__DOC__.equals(key)) { |
| 2317 | + // CPython sets tp_doc to a copy of dict['__doc__'], if that is a string. It |
| 2318 | + // forcibly encodes the string as UTF-8, and raises an error if that is not |
| 2319 | + // possible. |
| 2320 | + String doc = null; |
| 2321 | + if (value instanceof String) { |
| 2322 | + doc = (String) value; |
| 2323 | + } else if (value instanceof PString) { |
| 2324 | + doc = ((PString) value).getValue(); |
| 2325 | + } |
| 2326 | + if (doc != null) { |
| 2327 | + if (!canEncode(doc)) { |
| 2328 | + throw raise(PythonBuiltinClassType.UnicodeEncodeError, ErrorMessages.CANNOT_ENCODE_DOCSTR, doc); |
| 2329 | + } |
| 2330 | + } |
| 2331 | + pythonClass.setAttribute(key, value); |
2312 | 2332 | } else {
|
2313 | 2333 | pythonClass.setAttribute(key, value);
|
2314 | 2334 | }
|
@@ -2379,6 +2399,11 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
|
2379 | 2399 | return pythonClass;
|
2380 | 2400 | }
|
2381 | 2401 |
|
| 2402 | + @TruffleBoundary |
| 2403 | + private static boolean canEncode(String doc) { |
| 2404 | + return StandardCharsets.UTF_8.newEncoder().canEncode(doc); |
| 2405 | + } |
| 2406 | + |
2382 | 2407 | @TruffleBoundary
|
2383 | 2408 | private PTuple copySlots(String className, SequenceStorage slotList, int slotlen, boolean add_dict, boolean add_weak, PDict namespace, HashingStorageLibrary nslib) {
|
2384 | 2409 | SequenceStorage newSlots = new ObjectSequenceStorage(slotlen - PInt.intValue(add_dict) - PInt.intValue(add_weak));
|
|
0 commit comments