9898import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
9999
100100import java .math .BigInteger ;
101- import java .nio .charset .StandardCharsets ;
102101import java .util .Arrays ;
103102import java .util .List ;
104103
107106import com .oracle .graal .python .builtins .Builtin ;
108107import com .oracle .graal .python .builtins .CoreFunctions ;
109108import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
109+ import static com .oracle .graal .python .builtins .PythonBuiltinClassType .UnicodeEncodeError ;
110110import com .oracle .graal .python .builtins .PythonBuiltins ;
111111import com .oracle .graal .python .builtins .modules .WarningsModuleBuiltins .WarnNode ;
112112import com .oracle .graal .python .builtins .modules .WeakRefModuleBuiltins .GetWeakRefsNode ;
171171import com .oracle .graal .python .builtins .objects .set .PFrozenSet ;
172172import com .oracle .graal .python .builtins .objects .set .PSet ;
173173import 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 ;
174176import com .oracle .graal .python .builtins .objects .superobject .SuperObject ;
175177import com .oracle .graal .python .builtins .objects .traceback .PTraceback ;
176178import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
259261import com .oracle .truffle .api .profiles .BranchProfile ;
260262import com .oracle .truffle .api .profiles .ConditionProfile ;
261263import com .oracle .truffle .api .profiles .ValueProfile ;
264+ import com .oracle .graal .python .builtins .objects .str .StringBuiltins .IsIdentifierNode ;
262265
263266@ CoreFunctions (defineModule = BuiltinNames .BUILTINS )
264267public final class BuiltinConstructors extends PythonBuiltins {
@@ -2213,6 +2216,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
22132216 @ Cached GetItemsizeNode getItemSize ,
22142217 @ Cached WriteAttributeToObjectNode writeItemSize ,
22152218 @ Cached GetBestBaseClassNode getBestBaseNode ,
2219+ @ Cached IsIdentifierNode isIdentifier ,
22162220 @ Cached DictBuiltins .CopyNode copyDict ) {
22172221 // Determine the proper metatype to deal with this
22182222 String name = castStr .execute (wName );
@@ -2229,7 +2233,8 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
22292233
22302234 try {
22312235 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 );
22332238
22342239 for (DictEntry entry : hashingStoragelib .entries (namespace .getDictStorage ())) {
22352240 Object setName = getSetNameNode .execute (entry .value );
@@ -2325,7 +2330,8 @@ private String getModuleNameFromGlobals(PythonObject globals, HashingStorageLibr
23252330
23262331 private PythonClass typeMetaclass (VirtualFrame frame , String name , PTuple bases , PDict namespace , Object metaclass ,
23272332 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 ) {
23292335 Object [] array = ensureGetObjectArrayNode ().execute (bases );
23302336
23312337 PythonAbstractClass [] basesArray ;
@@ -2348,7 +2354,10 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
23482354
23492355 assert metaclass != null ;
23502356
2351- if (name .indexOf ('\0' ) != -1 ) {
2357+ if (!canEncodeUTF8 (name )) {
2358+ throw raise (UnicodeEncodeError , ErrorMessages .CANNOT_ENCODE_CLASSNAME , name );
2359+ }
2360+ if (containsNullCharacter (name )) {
23522361 throw raise (ValueError , ErrorMessages .TYPE_NAME_NO_NULL_CHARS );
23532362 }
23542363
@@ -2421,6 +2430,9 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
24212430 // Check valid slot name
24222431 if (element instanceof String ) {
24232432 slotName = (String ) element ;
2433+ if (!(boolean ) isIdentifier .call (frame , slotName )) {
2434+ throw raise (TypeError , ErrorMessages .SLOTS_MUST_BE_IDENTIFIERS );
2435+ }
24242436 } else {
24252437 throw raise (TypeError , ErrorMessages .MUST_BE_STRINGS_NOT_P , "__slots__ items" , element );
24262438 }
@@ -2555,8 +2567,8 @@ private void copyDictSlots(PythonClass pythonClass, PDict namespace, PythonObjec
25552567 doc = ((PString ) value ).getValue ();
25562568 }
25572569 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 );
25602572 }
25612573 }
25622574 pythonClass .setAttribute (key , value );
@@ -2592,11 +2604,6 @@ private void copyDictSlots(PythonClass pythonClass, PDict namespace, PythonObjec
25922604 }
25932605 }
25942606
2595- @ TruffleBoundary
2596- private static boolean canEncode (String doc ) {
2597- return StandardCharsets .UTF_8 .newEncoder ().canEncode (doc );
2598- }
2599-
26002607 @ TruffleBoundary
26012608 private PTuple copySlots (String className , SequenceStorage slotList , int slotlen , boolean add_dict , boolean add_weak , PDict namespace , HashingStorageLibrary nslib ) {
26022609 SequenceStorage newSlots = new ObjectSequenceStorage (slotlen - PInt .intValue (add_dict ) - PInt .intValue (add_weak ));
@@ -2637,7 +2644,7 @@ private String mangle(String privateobj, String ident) {
26372644 // Name mangling: __private becomes _classname__private. This is independent from how
26382645 // the name is used.
26392646 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 ) != '_' ) {
26412648 return ident ;
26422649 }
26432650 nlen = ident .length ();
0 commit comments