@@ -318,6 +318,7 @@ typedef struct {
318318    const  Tcl_ObjType  * BignumType ;
319319    const  Tcl_ObjType  * ListType ;
320320    const  Tcl_ObjType  * StringType ;
321+     const  Tcl_ObjType  * UTF32StringType ;
321322} TkappObject ;
322323
323324#define  Tkapp_Interp (v ) (((TkappObject *) (v))->interp)
@@ -588,14 +589,40 @@ Tkapp_New(const char *screenName, const char *className,
588589    }
589590
590591    v -> OldBooleanType  =  Tcl_GetObjType ("boolean" );
591-     v -> BooleanType  =  Tcl_GetObjType ("booleanString" );
592-     v -> ByteArrayType  =  Tcl_GetObjType ("bytearray" );
592+     {
593+         Tcl_Obj  * value ;
594+         int  boolValue ;
595+ 
596+         /* Tcl 8.5 "booleanString" type is not registered 
597+            and is renamed to "boolean" in Tcl 9.0. 
598+            Based on approach suggested at 
599+            https://core.tcl-lang.org/tcl/info/3bb3bcf2da5b */ 
600+         value  =  Tcl_NewStringObj ("true" , -1 );
601+         Tcl_GetBooleanFromObj (NULL , value , & boolValue );
602+         v -> BooleanType  =  value -> typePtr ;
603+         Tcl_DecrRefCount (value );
604+ 
605+         // "bytearray" type is not registered in Tcl 9.0 
606+         value  =  Tcl_NewByteArrayObj (NULL , 0 );
607+         v -> ByteArrayType  =  value -> typePtr ;
608+         Tcl_DecrRefCount (value );
609+     }
593610    v -> DoubleType  =  Tcl_GetObjType ("double" );
611+     /* TIP 484 suggests retrieving the "int" type without Tcl_GetObjType("int") 
612+        since it is no longer registered in Tcl 9.0. But even though Tcl 8.7 
613+        only uses the "wideInt" type on platforms with 32-bit long, it still has 
614+        a registered "int" type, which FromObj() should recognize just in case. */ 
594615    v -> IntType  =  Tcl_GetObjType ("int" );
616+     if  (v -> IntType  ==  NULL ) {
617+         Tcl_Obj  * value  =  Tcl_NewIntObj (0 );
618+         v -> IntType  =  value -> typePtr ;
619+         Tcl_DecrRefCount (value );
620+     }
595621    v -> WideIntType  =  Tcl_GetObjType ("wideInt" );
596622    v -> BignumType  =  Tcl_GetObjType ("bignum" );
597623    v -> ListType  =  Tcl_GetObjType ("list" );
598624    v -> StringType  =  Tcl_GetObjType ("string" );
625+     v -> UTF32StringType  =  Tcl_GetObjType ("utf32string" );
599626
600627    /* Delete the 'exit' command, which can screw things up */ 
601628    Tcl_DeleteCommand (v -> interp , "exit" );
@@ -1124,14 +1151,6 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value)
11241151        return  PyFloat_FromDouble (value -> internalRep .doubleValue );
11251152    }
11261153
1127-     if  (value -> typePtr  ==  tkapp -> IntType ) {
1128-         long  longValue ;
1129-         if  (Tcl_GetLongFromObj (interp , value , & longValue ) ==  TCL_OK )
1130-             return  PyLong_FromLong (longValue );
1131-         /* If there is an error in the long conversion, 
1132-            fall through to wideInt handling. */ 
1133-     }
1134- 
11351154    if  (value -> typePtr  ==  tkapp -> IntType  || 
11361155        value -> typePtr  ==  tkapp -> WideIntType ) {
11371156        result  =  fromWideIntObj (tkapp , value );
@@ -1176,17 +1195,12 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value)
11761195        return  result ;
11771196    }
11781197
1179-     if  (value -> typePtr  ==  tkapp -> StringType ) {
1198+     if  (value -> typePtr  ==  tkapp -> StringType  || 
1199+         value -> typePtr  ==  tkapp -> UTF32StringType )
1200+     {
11801201        return  unicodeFromTclObj (value );
11811202    }
11821203
1183-     if  (tkapp -> BooleanType  ==  NULL  && 
1184-         strcmp (value -> typePtr -> name , "booleanString" ) ==  0 ) {
1185-         /* booleanString type is not registered in Tcl */ 
1186-         tkapp -> BooleanType  =  value -> typePtr ;
1187-         return  fromBoolean (tkapp , value );
1188-     }
1189- 
11901204    if  (tkapp -> BignumType  ==  NULL  && 
11911205        strcmp (value -> typePtr -> name , "bignum" ) ==  0 ) {
11921206        /* bignum type is not registered in Tcl */ 
0 commit comments