summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-05-31 10:42:24 (GMT)
committerGitHub <noreply@github.com>2024-05-31 10:42:24 (GMT)
commit5539bd9df2b8301c9ec5fd1e1de0cb065a591c16 (patch)
tree479b7f95581b1b05f64ef827089d08eaed1ea89e /Modules
parent38bf39cb4be279cce6c97da26afcc60859a01571 (diff)
downloadcpython-5539bd9df2b8301c9ec5fd1e1de0cb065a591c16.zip
cpython-5539bd9df2b8301c9ec5fd1e1de0cb065a591c16.tar.gz
cpython-5539bd9df2b8301c9ec5fd1e1de0cb065a591c16.tar.bz2
[3.13] gh-103194: Fix Tkinter’s Tcl value type handling for Tcl 8.7/9.0 (GH-103846) (GH-119830)
Some of standard Tcl types were renamed, removed, or no longer registered in Tcl 8.7/9.0. This change fixes automatic conversion of Tcl values to Python values to avoid returning a Tcl_Obj where the primary Python types (int, bool, str, bytes) were returned in older Tcl. (cherry picked from commit 94e9585e99abc2d060cedc77b3c03e06b4a0a9c4) Co-authored-by: Christopher Chavez <chrischavez@gmx.us>
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_tkinter.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index c7e271f..0cff36d 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -318,6 +318,7 @@ typedef struct {
const Tcl_ObjType *BignumType;
const Tcl_ObjType *ListType;
const Tcl_ObjType *StringType;
+ const Tcl_ObjType *UTF32StringType;
} TkappObject;
#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
@@ -588,14 +589,40 @@ Tkapp_New(const char *screenName, const char *className,
}
v->OldBooleanType = Tcl_GetObjType("boolean");
- v->BooleanType = Tcl_GetObjType("booleanString");
- v->ByteArrayType = Tcl_GetObjType("bytearray");
+ {
+ Tcl_Obj *value;
+ int boolValue;
+
+ /* Tcl 8.5 "booleanString" type is not registered
+ and is renamed to "boolean" in Tcl 9.0.
+ Based on approach suggested at
+ https://core.tcl-lang.org/tcl/info/3bb3bcf2da5b */
+ value = Tcl_NewStringObj("true", -1);
+ Tcl_GetBooleanFromObj(NULL, value, &boolValue);
+ v->BooleanType = value->typePtr;
+ Tcl_DecrRefCount(value);
+
+ // "bytearray" type is not registered in Tcl 9.0
+ value = Tcl_NewByteArrayObj(NULL, 0);
+ v->ByteArrayType = value->typePtr;
+ Tcl_DecrRefCount(value);
+ }
v->DoubleType = Tcl_GetObjType("double");
+ /* TIP 484 suggests retrieving the "int" type without Tcl_GetObjType("int")
+ since it is no longer registered in Tcl 9.0. But even though Tcl 8.7
+ only uses the "wideInt" type on platforms with 32-bit long, it still has
+ a registered "int" type, which FromObj() should recognize just in case. */
v->IntType = Tcl_GetObjType("int");
+ if (v->IntType == NULL) {
+ Tcl_Obj *value = Tcl_NewIntObj(0);
+ v->IntType = value->typePtr;
+ Tcl_DecrRefCount(value);
+ }
v->WideIntType = Tcl_GetObjType("wideInt");
v->BignumType = Tcl_GetObjType("bignum");
v->ListType = Tcl_GetObjType("list");
v->StringType = Tcl_GetObjType("string");
+ v->UTF32StringType = Tcl_GetObjType("utf32string");
/* Delete the 'exit' command, which can screw things up */
Tcl_DeleteCommand(v->interp, "exit");
@@ -1124,14 +1151,6 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value)
return PyFloat_FromDouble(value->internalRep.doubleValue);
}
- if (value->typePtr == tkapp->IntType) {
- long longValue;
- if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK)
- return PyLong_FromLong(longValue);
- /* If there is an error in the long conversion,
- fall through to wideInt handling. */
- }
-
if (value->typePtr == tkapp->IntType ||
value->typePtr == tkapp->WideIntType) {
result = fromWideIntObj(tkapp, value);
@@ -1176,17 +1195,12 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value)
return result;
}
- if (value->typePtr == tkapp->StringType) {
+ if (value->typePtr == tkapp->StringType ||
+ value->typePtr == tkapp->UTF32StringType)
+ {
return unicodeFromTclObj(value);
}
- if (tkapp->BooleanType == NULL &&
- strcmp(value->typePtr->name, "booleanString") == 0) {
- /* booleanString type is not registered in Tcl */
- tkapp->BooleanType = value->typePtr;
- return fromBoolean(tkapp, value);
- }
-
if (tkapp->BignumType == NULL &&
strcmp(value->typePtr->name, "bignum") == 0) {
/* bignum type is not registered in Tcl */