Commit f7de3dd0 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #21526: Tkinter now supports new boolean type in Tcl 8.5.

parent f41f8f99
...@@ -378,6 +378,21 @@ class TclTest(unittest.TestCase): ...@@ -378,6 +378,21 @@ class TclTest(unittest.TestCase):
if tcl_version >= (8, 5): if tcl_version >= (8, 5):
check('2**64', True) check('2**64', True)
def test_booleans(self):
tcl = self.interp
def check(expr, expected):
result = tcl.call('expr', expr)
self.assertEqual(result, expected)
self.assertIsInstance(result, int)
check('true', True)
check('yes', True)
check('on', True)
check('false', False)
check('no', False)
check('off', False)
check('1 < 2', True)
check('1 > 2', False)
def test_passing_values(self): def test_passing_values(self):
def passValue(value): def passValue(value):
return self.interp.call('set', '_', value) return self.interp.call('set', '_', value)
......
...@@ -24,6 +24,8 @@ Core and Builtins ...@@ -24,6 +24,8 @@ Core and Builtins
Library Library
------- -------
- Issue #21526: Tkinter now supports new boolean type in Tcl 8.5.
- Issue #23838: linecache now clears the cache and returns an empty result on - Issue #23838: linecache now clears the cache and returns an empty result on
MemoryError. MemoryError.
......
...@@ -242,13 +242,14 @@ typedef struct { ...@@ -242,13 +242,14 @@ typedef struct {
int dispatching; int dispatching;
/* We cannot include tclInt.h, as this is internal. /* We cannot include tclInt.h, as this is internal.
So we cache interesting types here. */ So we cache interesting types here. */
Tcl_ObjType *BooleanType; const Tcl_ObjType *OldBooleanType;
Tcl_ObjType *ByteArrayType; const Tcl_ObjType *BooleanType;
Tcl_ObjType *DoubleType; const Tcl_ObjType *ByteArrayType;
Tcl_ObjType *IntType; const Tcl_ObjType *DoubleType;
Tcl_ObjType *ListType; const Tcl_ObjType *IntType;
Tcl_ObjType *ProcBodyType; const Tcl_ObjType *ListType;
Tcl_ObjType *StringType; const Tcl_ObjType *ProcBodyType;
const Tcl_ObjType *StringType;
} TkappObject; } TkappObject;
#define Tkapp_Interp(v) (((TkappObject *) (v))->interp) #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
...@@ -577,7 +578,8 @@ Tkapp_New(char *screenName, char *className, ...@@ -577,7 +578,8 @@ Tkapp_New(char *screenName, char *className,
} }
#endif #endif
v->BooleanType = Tcl_GetObjType("boolean"); v->OldBooleanType = Tcl_GetObjType("boolean");
v->BooleanType = Tcl_GetObjType("booleanString");
v->ByteArrayType = Tcl_GetObjType("bytearray"); v->ByteArrayType = Tcl_GetObjType("bytearray");
v->DoubleType = Tcl_GetObjType("double"); v->DoubleType = Tcl_GetObjType("double");
v->IntType = Tcl_GetObjType("int"); v->IntType = Tcl_GetObjType("int");
...@@ -979,20 +981,29 @@ AsObj(PyObject *value) ...@@ -979,20 +981,29 @@ AsObj(PyObject *value)
} }
} }
static PyObject *
fromBoolean(PyObject* tkapp, Tcl_Obj *value)
{
int boolValue;
if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR)
return Tkinter_Error(tkapp);
return PyBool_FromLong(boolValue);
}
static PyObject* static PyObject*
FromObj(PyObject* tkapp, Tcl_Obj *value) FromObj(PyObject* tkapp, Tcl_Obj *value)
{ {
PyObject *result = NULL; PyObject *result = NULL;
TkappObject *app = (TkappObject*)tkapp; TkappObject *app = (TkappObject*)tkapp;
Tcl_Interp *interp = Tkapp_Interp(tkapp);
if (value->typePtr == NULL) { if (value->typePtr == NULL) {
return unicodeFromTclStringAndSize(value->bytes, value->length); return unicodeFromTclStringAndSize(value->bytes, value->length);
} }
if (value->typePtr == app->BooleanType) { if (value->typePtr == app->BooleanType ||
result = value->internalRep.longValue ? Py_True : Py_False; value->typePtr == app->OldBooleanType) {
Py_INCREF(result); return fromBoolean(tkapp, value);
return result;
} }
if (value->typePtr == app->ByteArrayType) { if (value->typePtr == app->ByteArrayType) {
...@@ -1015,15 +1026,14 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) ...@@ -1015,15 +1026,14 @@ FromObj(PyObject* tkapp, Tcl_Obj *value)
PyObject *elem; PyObject *elem;
Tcl_Obj *tcl_elem; Tcl_Obj *tcl_elem;
status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size); status = Tcl_ListObjLength(interp, value, &size);
if (status == TCL_ERROR) if (status == TCL_ERROR)
return Tkinter_Error(tkapp); return Tkinter_Error(tkapp);
result = PyTuple_New(size); result = PyTuple_New(size);
if (!result) if (!result)
return NULL; return NULL;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
status = Tcl_ListObjIndex(Tkapp_Interp(tkapp), status = Tcl_ListObjIndex(interp, value, i, &tcl_elem);
value, i, &tcl_elem);
if (status == TCL_ERROR) { if (status == TCL_ERROR) {
Py_DECREF(result); Py_DECREF(result);
return Tkinter_Error(tkapp); return Tkinter_Error(tkapp);
...@@ -1048,6 +1058,15 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) ...@@ -1048,6 +1058,15 @@ FromObj(PyObject* tkapp, Tcl_Obj *value)
Tcl_GetCharLength(value)); Tcl_GetCharLength(value));
} }
#if TK_VERSION_HEX >= 0x08050000
if (app->BooleanType == NULL &&
strcmp(value->typePtr->name, "booleanString") == 0) {
/* booleanString type is not registered in Tcl */
app->BooleanType = value->typePtr;
return fromBoolean(tkapp, value);
}
#endif
return newPyTclObject(value); return newPyTclObject(value);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment