98
98
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
99
99
100
100
import java .math .BigInteger ;
101
- import java .nio .charset .StandardCharsets ;
102
101
import java .util .Arrays ;
103
102
import java .util .List ;
104
103
107
106
import com .oracle .graal .python .builtins .Builtin ;
108
107
import com .oracle .graal .python .builtins .CoreFunctions ;
109
108
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
109
+ import static com .oracle .graal .python .builtins .PythonBuiltinClassType .UnicodeEncodeError ;
110
110
import com .oracle .graal .python .builtins .PythonBuiltins ;
111
111
import com .oracle .graal .python .builtins .modules .WarningsModuleBuiltins .WarnNode ;
112
112
import com .oracle .graal .python .builtins .modules .WeakRefModuleBuiltins .GetWeakRefsNode ;
171
171
import com .oracle .graal .python .builtins .objects .set .PFrozenSet ;
172
172
import com .oracle .graal .python .builtins .objects .set .PSet ;
173
173
import com .oracle .graal .python .builtins .objects .str .PString ;
174
+ import static com .oracle .graal .python .builtins .objects .str .StringUtils .canEncodeUTF8 ;
175
+ import static com .oracle .graal .python .builtins .objects .str .StringUtils .containsNullCharacter ;
174
176
import com .oracle .graal .python .builtins .objects .superobject .SuperObject ;
175
177
import com .oracle .graal .python .builtins .objects .traceback .PTraceback ;
176
178
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
259
261
import com .oracle .truffle .api .profiles .BranchProfile ;
260
262
import com .oracle .truffle .api .profiles .ConditionProfile ;
261
263
import com .oracle .truffle .api .profiles .ValueProfile ;
264
+ import com .oracle .graal .python .builtins .objects .str .StringBuiltins .IsIdentifierNode ;
262
265
263
266
@ CoreFunctions (defineModule = BuiltinNames .BUILTINS )
264
267
public final class BuiltinConstructors extends PythonBuiltins {
@@ -2213,6 +2216,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
2213
2216
@ Cached GetItemsizeNode getItemSize ,
2214
2217
@ Cached WriteAttributeToObjectNode writeItemSize ,
2215
2218
@ Cached GetBestBaseClassNode getBestBaseNode ,
2219
+ @ Cached IsIdentifierNode isIdentifier ,
2216
2220
@ Cached DictBuiltins .CopyNode copyDict ) {
2217
2221
// Determine the proper metatype to deal with this
2218
2222
String name = castStr .execute (wName );
@@ -2229,7 +2233,8 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
2229
2233
2230
2234
try {
2231
2235
PDict namespace = (PDict ) copyDict .call (frame , namespaceOrig );
2232
- PythonClass newType = typeMetaclass (frame , name , bases , namespace , metaclass , lib , hashingStoragelib , getDictAttrNode , getWeakRefAttrNode , getBestBaseNode , getItemSize , writeItemSize );
2236
+ PythonClass newType = typeMetaclass (frame , name , bases , namespace , metaclass , lib , hashingStoragelib , getDictAttrNode , getWeakRefAttrNode , getBestBaseNode , getItemSize , writeItemSize ,
2237
+ isIdentifier );
2233
2238
2234
2239
for (DictEntry entry : hashingStoragelib .entries (namespace .getDictStorage ())) {
2235
2240
Object setName = getSetNameNode .execute (entry .value );
@@ -2325,7 +2330,8 @@ private String getModuleNameFromGlobals(PythonObject globals, HashingStorageLibr
2325
2330
2326
2331
private PythonClass typeMetaclass (VirtualFrame frame , String name , PTuple bases , PDict namespace , Object metaclass ,
2327
2332
PythonObjectLibrary lib , HashingStorageLibrary hashingStorageLib , LookupAttributeInMRONode getDictAttrNode ,
2328
- LookupAttributeInMRONode getWeakRefAttrNode , GetBestBaseClassNode getBestBaseNode , GetItemsizeNode getItemSize , WriteAttributeToObjectNode writeItemSize ) {
2333
+ LookupAttributeInMRONode getWeakRefAttrNode , GetBestBaseClassNode getBestBaseNode , GetItemsizeNode getItemSize , WriteAttributeToObjectNode writeItemSize ,
2334
+ IsIdentifierNode isIdentifier ) {
2329
2335
Object [] array = ensureGetObjectArrayNode ().execute (bases );
2330
2336
2331
2337
PythonAbstractClass [] basesArray ;
@@ -2348,7 +2354,10 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
2348
2354
2349
2355
assert metaclass != null ;
2350
2356
2351
- if (name .indexOf ('\0' ) != -1 ) {
2357
+ if (!canEncodeUTF8 (name )) {
2358
+ throw raise (UnicodeEncodeError , ErrorMessages .CANNOT_ENCODE_CLASSNAME , name );
2359
+ }
2360
+ if (containsNullCharacter (name )) {
2352
2361
throw raise (ValueError , ErrorMessages .TYPE_NAME_NO_NULL_CHARS );
2353
2362
}
2354
2363
@@ -2421,6 +2430,9 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
2421
2430
// Check valid slot name
2422
2431
if (element instanceof String ) {
2423
2432
slotName = (String ) element ;
2433
+ if (!(boolean ) isIdentifier .call (frame , slotName )) {
2434
+ throw raise (TypeError , ErrorMessages .SLOTS_MUST_BE_IDENTIFIERS );
2435
+ }
2424
2436
} else {
2425
2437
throw raise (TypeError , ErrorMessages .MUST_BE_STRINGS_NOT_P , "__slots__ items" , element );
2426
2438
}
@@ -2555,8 +2567,8 @@ private void copyDictSlots(PythonClass pythonClass, PDict namespace, PythonObjec
2555
2567
doc = ((PString ) value ).getValue ();
2556
2568
}
2557
2569
if (doc != null ) {
2558
- if (!canEncode (doc )) {
2559
- throw raise (PythonBuiltinClassType . UnicodeEncodeError , ErrorMessages .CANNOT_ENCODE_DOCSTR , doc );
2570
+ if (!canEncodeUTF8 (doc )) {
2571
+ throw raise (UnicodeEncodeError , ErrorMessages .CANNOT_ENCODE_DOCSTR , doc );
2560
2572
}
2561
2573
}
2562
2574
pythonClass .setAttribute (key , value );
@@ -2592,11 +2604,6 @@ private void copyDictSlots(PythonClass pythonClass, PDict namespace, PythonObjec
2592
2604
}
2593
2605
}
2594
2606
2595
- @ TruffleBoundary
2596
- private static boolean canEncode (String doc ) {
2597
- return StandardCharsets .UTF_8 .newEncoder ().canEncode (doc );
2598
- }
2599
-
2600
2607
@ TruffleBoundary
2601
2608
private PTuple copySlots (String className , SequenceStorage slotList , int slotlen , boolean add_dict , boolean add_weak , PDict namespace , HashingStorageLibrary nslib ) {
2602
2609
SequenceStorage newSlots = new ObjectSequenceStorage (slotlen - PInt .intValue (add_dict ) - PInt .intValue (add_weak ));
@@ -2637,7 +2644,7 @@ private String mangle(String privateobj, String ident) {
2637
2644
// Name mangling: __private becomes _classname__private. This is independent from how
2638
2645
// the name is used.
2639
2646
int nlen , plen , ipriv ;
2640
- if (privateobj == null || ident .charAt (0 ) != '_' || ident .charAt (1 ) != '_' ) {
2647
+ if (privateobj == null || ident .equals ( "_" ) || ident . charAt (0 ) != '_' || ident .charAt (1 ) != '_' ) {
2641
2648
return ident ;
2642
2649
}
2643
2650
nlen = ident .length ();
0 commit comments