diff options
Diffstat (limited to 'Modules/_tkinter.c')
-rw-r--r-- | Modules/_tkinter.c | 583 |
1 files changed, 248 insertions, 335 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 40c8be2ce7c..23906dea903 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -44,7 +44,7 @@ Copyright (C) 1994 Steen Lumholt. #ifndef PyBool_Check #define PyBool_Check(o) 0 -#define PyBool_FromLong PyInt_FromLong +#define PyBool_FromLong PyLong_FromLong #endif /* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, @@ -281,7 +281,7 @@ static PyObject *valInCmd; static PyObject *trbInCmd; #ifdef TKINTER_PROTECT_LOADTK -static int tk_load_failed; +static int tk_load_failed = 0; #endif @@ -338,9 +338,8 @@ WaitForMainloop(TkappObject* self) static char * AsString(PyObject *value, PyObject *tmp) { - if (PyString_Check(value)) - return PyString_AsString(value); -#ifdef Py_USING_UNICODE + if (PyBytes_Check(value)) + return PyBytes_AsString(value); else if (PyUnicode_Check(value)) { PyObject *v = PyUnicode_AsUTF8String(value); if (v == NULL) @@ -350,9 +349,8 @@ AsString(PyObject *value, PyObject *tmp) return NULL; } Py_DECREF(v); - return PyString_AsString(v); + return PyBytes_AsString(v); } -#endif else { PyObject *v = PyObject_Str(value); if (v == NULL) @@ -362,7 +360,7 @@ AsString(PyObject *value, PyObject *tmp) return NULL; } Py_DECREF(v); - return PyString_AsString(v); + return PyBytes_AsString(v); } } @@ -465,13 +463,13 @@ Split(char *list) * Could be a quoted string containing funnies, e.g. {"}. * Return the string itself. */ - return PyString_FromString(list); + return PyUnicode_FromString(list); } if (argc == 0) - v = PyString_FromString(""); + v = PyUnicode_FromString(""); else if (argc == 1) - v = PyString_FromString(argv[0]); + v = PyUnicode_FromString(argv[0]); else if ((v = PyTuple_New(argc)) != NULL) { int i; PyObject *w; @@ -533,10 +531,10 @@ SplitObj(PyObject *arg) return result; /* Fall through, returning arg. */ } - else if (PyString_Check(arg)) { + else if (PyBytes_Check(arg)) { int argc; char **argv; - char *list = PyString_AsString(arg); + char *list = PyBytes_AsString(arg); if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { Py_INCREF(arg); @@ -544,7 +542,7 @@ SplitObj(PyObject *arg) } Tcl_Free(FREECAST argv); if (argc > 1) - return Split(PyString_AsString(arg)); + return Split(PyBytes_AsString(arg)); /* Fall through, returning arg. */ } Py_INCREF(arg); @@ -602,7 +600,7 @@ static void EnableEventHook(void); /* Forward */ static void DisableEventHook(void); /* Forward */ static TkappObject * -Tkapp_New(char *screenName, char *baseName, char *className, +Tkapp_New(char *screenName, char *className, int interactive, int wantobjects, int wantTk, int sync, char *use) { TkappObject *v; @@ -758,7 +756,7 @@ typedef struct { PyObject *string; /* This cannot cause cycles. */ } PyTclObject; -staticforward PyTypeObject PyTclObject_Type; +static PyTypeObject PyTclObject_Type; #define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type) static PyObject * @@ -782,17 +780,6 @@ PyTclObject_dealloc(PyTclObject *self) PyObject_Del(self); } -static PyObject * -PyTclObject_str(PyTclObject *self) -{ - if (self->string && PyString_Check(self->string)) { - Py_INCREF(self->string); - return self->string; - } - /* XXX Could cache value if it is an ASCII string. */ - return PyString_FromString(Tcl_GetString(self->value)); -} - static char* PyTclObject_TclString(PyObject *self) { @@ -801,32 +788,16 @@ PyTclObject_TclString(PyObject *self) /* Like _str, but create Unicode if necessary. */ PyDoc_STRVAR(PyTclObject_string__doc__, -"the string representation of this object, either as string or Unicode"); +"the string representation of this object, either as str or bytes"); static PyObject * PyTclObject_string(PyTclObject *self, void *ignored) { char *s; - int i, len; + int len; if (!self->string) { s = Tcl_GetStringFromObj(self->value, &len); - for (i = 0; i < len; i++) - if (s[i] & 0x80) - break; -#ifdef Py_USING_UNICODE - if (i == len) - /* It is an ASCII string. */ - self->string = PyString_FromStringAndSize(s, len); - else { - self->string = PyUnicode_DecodeUTF8(s, len, "strict"); - if (!self->string) { - PyErr_Clear(); - self->string = PyString_FromStringAndSize(s, len); - } - } -#else - self->string = PyString_FromStringAndSize(s, len); -#endif + self->string = PyUnicode_FromStringAndSize(s, len); if (!self->string) return NULL; } @@ -834,11 +805,8 @@ PyTclObject_string(PyTclObject *self, void *ignored) return self->string; } -#ifdef Py_USING_UNICODE -PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode"); - static PyObject * -PyTclObject_unicode(PyTclObject *self, void *ignored) +PyTclObject_str(PyTclObject *self, void *ignored) { char *s; int len; @@ -850,26 +818,67 @@ PyTclObject_unicode(PyTclObject *self, void *ignored) s = Tcl_GetStringFromObj(self->value, &len); return PyUnicode_DecodeUTF8(s, len, "strict"); } -#endif static PyObject * PyTclObject_repr(PyTclObject *self) { - char buf[50]; - PyOS_snprintf(buf, 50, "<%s object at %p>", - self->value->typePtr->name, self->value); - return PyString_FromString(buf); + return PyUnicode_FromFormat("<%s object at %p>", + self->value->typePtr->name, self->value); } -static int -PyTclObject_cmp(PyTclObject *self, PyTclObject *other) +#define TEST_COND(cond) ((cond) ? Py_True : Py_False) + +static PyObject * +PyTclObject_richcompare(PyObject *self, PyObject *other, int op) { - int res; - res = strcmp(Tcl_GetString(self->value), - Tcl_GetString(other->value)); - if (res < 0) return -1; - if (res > 0) return 1; - return 0; + int result; + PyObject *v; + + /* neither argument should be NULL, unless something's gone wrong */ + if (self == NULL || other == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + /* both arguments should be instances of PyTclObject */ + if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) { + v = Py_NotImplemented; + goto finished; + } + + if (self == other) + /* fast path when self and other are identical */ + result = 0; + else + result = strcmp(Tcl_GetString(((PyTclObject *)self)->value), + Tcl_GetString(((PyTclObject *)other)->value)); + /* Convert return value to a Boolean */ + switch (op) { + case Py_EQ: + v = TEST_COND(result == 0); + break; + case Py_NE: + v = TEST_COND(result != 0); + break; + case Py_LE: + v = TEST_COND(result <= 0); + break; + case Py_GE: + v = TEST_COND(result >= 0); + break; + case Py_LT: + v = TEST_COND(result < 0); + break; + case Py_GT: + v = TEST_COND(result > 0); + break; + default: + PyErr_BadArgument(); + return NULL; + } + finished: + Py_INCREF(v); + return v; } PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); @@ -877,7 +886,7 @@ PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); static PyObject* get_typename(PyTclObject* obj, void* ignored) { - return PyString_FromString(obj->value->typePtr->name); + return PyUnicode_FromString(obj->value->typePtr->name); } @@ -888,71 +897,69 @@ static PyGetSetDef PyTclObject_getsetlist[] = { {0}, }; -static PyMethodDef PyTclObject_methods[] = { -#ifdef Py_USING_UNICODE - {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS, - PyTclObject_unicode__doc__}, -#endif - {0} -}; - -statichere PyTypeObject PyTclObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ +static PyTypeObject PyTclObject_Type = { + PyVarObject_HEAD_INIT(NULL, 0) "_tkinter.Tcl_Obj", /*tp_name*/ - sizeof(PyTclObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ + sizeof(PyTclObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ /* methods */ - (destructor)PyTclObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - (cmpfunc)PyTclObject_cmp, /*tp_compare*/ + (destructor)PyTclObject_dealloc,/*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ (reprfunc)PyTclObject_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - (reprfunc)PyTclObject_str, /*tp_str*/ - PyObject_GenericGetAttr,/*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PyTclObject_methods, /*tp_methods*/ - 0, /*tp_members*/ - PyTclObject_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + (reprfunc)PyTclObject_str, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + PyTclObject_richcompare, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + PyTclObject_getsetlist, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ }; static Tcl_Obj* AsObj(PyObject *value) { Tcl_Obj *result; + long longVal; + int overflow; - if (PyString_Check(value)) - return Tcl_NewStringObj(PyString_AS_STRING(value), - PyString_GET_SIZE(value)); + if (PyBytes_Check(value)) + return Tcl_NewStringObj(PyBytes_AS_STRING(value), + PyBytes_GET_SIZE(value)); else if (PyBool_Check(value)) return Tcl_NewBooleanObj(PyObject_IsTrue(value)); - else if (PyInt_Check(value)) - return Tcl_NewLongObj(PyInt_AS_LONG(value)); + else if (PyLong_CheckExact(value) && + ((longVal = PyLong_AsLongAndOverflow(value, &overflow)), + !overflow)) { + /* If there is an overflow in the long conversion, + fall through to default object handling. */ + return Tcl_NewLongObj(longVal); + } else if (PyFloat_Check(value)) return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); else if (PyTuple_Check(value)) { @@ -967,7 +974,6 @@ AsObj(PyObject *value) ckfree(FREECAST argv); return result; } -#ifdef Py_USING_UNICODE else if (PyUnicode_Check(value)) { Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value); Py_ssize_t size = PyUnicode_GET_SIZE(value); @@ -987,8 +993,10 @@ AsObj(PyObject *value) for (i = 0; i < size; i++) { if (inbuf[i] >= 0x10000) { /* Tcl doesn't do UTF-16, yet. */ - PyErr_SetString(PyExc_ValueError, - "unsupported character"); + PyErr_Format(PyExc_ValueError, + "character U+%x is above the range " + "(U+0000-U+FFFF) allowed by Tcl", + inbuf[i]); ckfree(FREECAST outbuf); return NULL; } @@ -1002,7 +1010,6 @@ AsObj(PyObject *value) #endif } -#endif else if(PyTclObject_Check(value)) { Tcl_Obj *v = ((PyTclObject*)value)->value; Tcl_IncrRefCount(v); @@ -1025,31 +1032,8 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) TkappObject *app = (TkappObject*)tkapp; if (value->typePtr == NULL) { - /* If the result contains any bytes with the top bit set, - it's UTF-8 and we should decode it to Unicode */ -#ifdef Py_USING_UNICODE - int i; - char *s = value->bytes; - int len = value->length; - for (i = 0; i < len; i++) { - if (value->bytes[i] & 0x80) - break; - } - - if (i == value->length) - result = PyString_FromStringAndSize(s, len); - else { - /* Convert UTF-8 to Unicode string */ - result = PyUnicode_DecodeUTF8(s, len, "strict"); - if (result == NULL) { - PyErr_Clear(); - result = PyString_FromStringAndSize(s, len); - } - } -#else - result = PyString_FromStringAndSize(value->bytes, value->length); -#endif - return result; + return PyUnicode_FromStringAndSize(value->bytes, + value->length); } if (value->typePtr == app->BooleanType) { @@ -1061,7 +1045,7 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) if (value->typePtr == app->ByteArrayType) { int size; char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); - return PyString_FromStringAndSize(data, size); + return PyBytes_FromStringAndSize(data, size); } if (value->typePtr == app->DoubleType) { @@ -1069,7 +1053,7 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } if (value->typePtr == app->IntType) { - return PyInt_FromLong(value->internalRep.longValue); + return PyLong_FromLong(value->internalRep.longValue); } if (value->typePtr == app->ListType) { @@ -1106,7 +1090,6 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } if (value->typePtr == app->StringType) { -#ifdef Py_USING_UNICODE #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3 PyObject *result; int size; @@ -1126,12 +1109,6 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) return PyUnicode_FromUnicode(Tcl_GetUnicode(value), Tcl_GetCharLength(value)); #endif -#else - int size; - char *c; - c = Tcl_GetStringFromObj(value, &size); - return PyString_FromStringAndSize(c, size); -#endif } return newPyTclObject(value); @@ -1233,30 +1210,7 @@ Tkapp_CallResult(TkappObject *self) const char *s = Tcl_GetStringResult(self->interp); const char *p = s; - /* If the result contains any bytes with the top bit set, - it's UTF-8 and we should decode it to Unicode */ -#ifdef Py_USING_UNICODE - while (*p != '\0') { - if (*p & 0x80) - break; - p++; - } - - if (*p == '\0') - res = PyString_FromStringAndSize(s, (int)(p-s)); - else { - /* Convert UTF-8 to Unicode string */ - p = strchr(p, '\0'); - res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict"); - if (res == NULL) { - PyErr_Clear(); - res = PyString_FromStringAndSize(s, (int)(p-s)); - } - } -#else - p = strchr(p, '\0'); - res = PyString_FromStringAndSize(s, (int)(p-s)); -#endif + res = PyUnicode_FromStringAndSize(s, (int)(p-s)); } return res; } @@ -1416,7 +1370,7 @@ Tkapp_GlobalCall(PyObject *self, PyObject *args) if (err == TCL_ERROR) res = Tkinter_Error(self); else - res = PyString_FromString(Tkapp_Result(self)); + res = PyUnicode_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL ckfree(cmd); } @@ -1442,7 +1396,7 @@ Tkapp_Eval(PyObject *self, PyObject *args) if (err == TCL_ERROR) res = Tkinter_Error(self); else - res = PyString_FromString(Tkapp_Result(self)); + res = PyUnicode_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1465,7 +1419,7 @@ Tkapp_GlobalEval(PyObject *self, PyObject *args) if (err == TCL_ERROR) res = Tkinter_Error(self); else - res = PyString_FromString(Tkapp_Result(self)); + res = PyUnicode_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1489,7 +1443,7 @@ Tkapp_EvalFile(PyObject *self, PyObject *args) res = Tkinter_Error(self); else - res = PyString_FromString(Tkapp_Result(self)); + res = PyUnicode_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1512,7 +1466,7 @@ Tkapp_Record(PyObject *self, PyObject *args) if (err == TCL_ERROR) res = Tkinter_Error(self); else - res = PyString_FromString(Tkapp_Result(self)); + res = PyUnicode_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1560,8 +1514,12 @@ static int varname_converter(PyObject *in, void *_out) { char **out = (char**)_out; - if (PyString_Check(in)) { - *out = PyString_AsString(in); + if (PyBytes_Check(in)) { + *out = PyBytes_AsString(in); + return 1; + } + if (PyUnicode_Check(in)) { + *out = _PyUnicode_AsString(in); return 1; } if (PyTclObject_Check(in)) { @@ -1731,7 +1689,7 @@ GetVar(PyObject *self, PyObject *args, int flags) res = FromObj(self, tres); } else { - res = PyString_FromString(Tcl_GetString(tres)); + res = PyUnicode_FromString(Tcl_GetString(tres)); } } LEAVE_OVERLAP_TCL @@ -1799,7 +1757,7 @@ Tkapp_GetInt(PyObject *self, PyObject *args) if (PyTuple_Size(args) == 1) { PyObject* o = PyTuple_GetItem(args, 0); - if (PyInt_Check(o)) { + if (PyLong_Check(o)) { Py_INCREF(o); return o; } @@ -1839,7 +1797,7 @@ Tkapp_GetBoolean(PyObject *self, PyObject *args) if (PyTuple_Size(args) == 1) { PyObject *o = PyTuple_GetItem(args, 0); - if (PyInt_Check(o)) { + if (PyLong_Check(o)) { Py_INCREF(o); return o; } @@ -1975,7 +1933,7 @@ Tkapp_SplitList(PyObject *self, PyObject *args) goto finally; for (i = 0; i < argc; i++) { - PyObject *s = PyString_FromString(argv[i]); + PyObject *s = PyUnicode_FromString(argv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); v = NULL; @@ -2016,7 +1974,7 @@ Tkapp_Merge(PyObject *self, PyObject *args) PyObject *res = NULL; if (s) { - res = PyString_FromString(s); + res = PyUnicode_FromString(s); ckfree(s); } @@ -2049,7 +2007,7 @@ static int PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; - PyObject *func, *arg, *res; + PyObject *self, *func, *arg, *res; int i, rv; Tcl_Obj *obj_res; @@ -2058,6 +2016,7 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) /* TBD: no error checking here since we know, via the * Tkapp_CreateCommand() that the client data is a two-tuple */ + self = data->self; func = data->func; /* Create argument list (argv1, ..., argvN) */ @@ -2065,8 +2024,20 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) return PythonCmd_Error(interp); for (i = 0; i < (argc - 1); i++) { - PyObject *s = PyString_FromString(argv[i + 1]); - if (!s || PyTuple_SetItem(arg, i, s)) { + PyObject *s = PyUnicode_FromString(argv[i + 1]); + if (!s) { + /* Is Tk leaking 0xC080 in %A - a "modified" utf-8 null? */ + if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) && + !strcmp(argv[i + 1], "\xC0\x80")) { + PyErr_Clear(); + /* Convert to "strict" utf-8 null */ + s = PyUnicode_FromString("\0"); + } else { + Py_DECREF(arg); + return PythonCmd_Error(interp); + } + } + if (PyTuple_SetItem(arg, i, s)) { Py_DECREF(arg); return PythonCmd_Error(interp); } @@ -2167,7 +2138,6 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) Py_INCREF(func); data->self = selfptr; data->func = func; - #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; @@ -2322,29 +2292,11 @@ Tkapp_CreateFileHandler(PyObject *self, PyObject *args) PyObject *file, *func; int mask, tfile; - if (!self && Py_Py3kWarningFlag) { - if (PyErr_Warn(PyExc_DeprecationWarning, - "_tkinter.createfilehandler is gone in 3.x") < 0) - return NULL; - } - if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func)) return NULL; -#ifdef WITH_THREAD - if (!self && !tcl_lock) { - /* We don't have the Tcl lock since Tcl is threaded. */ - PyErr_SetString(PyExc_RuntimeError, - "_tkinter.createfilehandler not supported " - "for threaded Tcl"); - return NULL; - } -#endif - - if (self) { - CHECK_TCL_APPARTMENT; - } + CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) @@ -2372,28 +2324,10 @@ Tkapp_DeleteFileHandler(PyObject *self, PyObject *args) PyObject *file; int tfile; - if (!self && Py_Py3kWarningFlag) { - if (PyErr_Warn(PyExc_DeprecationWarning, - "_tkinter.deletefilehandler is gone in 3.x") < 0) - return NULL; - } - if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) return NULL; -#ifdef WITH_THREAD - if (!self && !tcl_lock) { - /* We don't have the Tcl lock since Tcl is threaded. */ - PyErr_SetString(PyExc_RuntimeError, - "_tkinter.deletefilehandler not supported " - "for threaded Tcl"); - return NULL; - } -#endif - - if (self) { - CHECK_TCL_APPARTMENT; - } + CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) @@ -2485,13 +2419,7 @@ Tktt_Repr(PyObject *self) PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v, v->func == NULL ? ", handler deleted" : ""); - return PyString_FromString(buf); -} - -static PyObject * -Tktt_GetAttr(PyObject *self, char *name) -{ - return Py_FindMethod(Tktt_methods, self, name); + return PyUnicode_FromString(buf); } static PyTypeObject Tktt_Type = @@ -2502,14 +2430,28 @@ static PyTypeObject Tktt_Type = 0, /*tp_itemsize */ Tktt_Dealloc, /*tp_dealloc */ 0, /*tp_print */ - Tktt_GetAttr, /*tp_getattr */ + 0, /*tp_getattr */ 0, /*tp_setattr */ - 0, /*tp_compare */ + 0, /*tp_reserved */ Tktt_Repr, /*tp_repr */ 0, /*tp_as_number */ 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Tktt_methods, /*tp_methods*/ }; @@ -2551,12 +2493,6 @@ Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) PyObject *func; TkttObject *v; - if (!self && Py_Py3kWarningFlag) { - if (PyErr_Warn(PyExc_DeprecationWarning, - "_tkinter.createtimerhandler is gone in 3.x") < 0) - return NULL; - } - if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func)) return NULL; @@ -2565,19 +2501,7 @@ Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) return NULL; } -#ifdef WITH_THREAD - if (!self && !tcl_lock) { - /* We don't have the Tcl lock since Tcl is threaded. */ - PyErr_SetString(PyExc_RuntimeError, - "_tkinter.createtimerhandler not supported " - "for threaded Tcl"); - return NULL; - } -#endif - - if (self) { - CHECK_TCL_APPARTMENT; - } + CHECK_TCL_APPARTMENT; v = Tktt_New(func); if (v) { @@ -2600,29 +2524,11 @@ Tkapp_MainLoop(PyObject *selfptr, PyObject *args) PyThreadState *tstate = PyThreadState_Get(); #endif - if (!self && Py_Py3kWarningFlag) { - if (PyErr_Warn(PyExc_DeprecationWarning, - "_tkinter.mainloop is gone in 3.x") < 0) - return NULL; - } - if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) return NULL; -#ifdef WITH_THREAD - if (!self && !tcl_lock) { - /* We don't have the Tcl lock since Tcl is threaded. */ - PyErr_SetString(PyExc_RuntimeError, - "_tkinter.mainloop not supported " - "for threaded Tcl"); - return NULL; - } -#endif - - if (self) { - CHECK_TCL_APPARTMENT; - self->dispatching = 1; - } + CHECK_TCL_APPARTMENT; + self->dispatching = 1; quitMainLoop = 0; while (Tk_GetNumMainWindows() > threshold && @@ -2632,7 +2538,7 @@ Tkapp_MainLoop(PyObject *selfptr, PyObject *args) int result; #ifdef WITH_THREAD - if (self && self->threaded) { + if (self->threaded) { /* Allow other Python threads to run. */ ENTER_TCL result = Tcl_DoOneEvent(0); @@ -2654,15 +2560,13 @@ Tkapp_MainLoop(PyObject *selfptr, PyObject *args) #endif if (PyErr_CheckSignals() != 0) { - if (self) - self->dispatching = 0; + self->dispatching = 0; return NULL; } if (result < 0) break; } - if (self) - self->dispatching = 0; + self->dispatching = 0; quitMainLoop = 0; if (errorInCmd) { @@ -2681,12 +2585,6 @@ Tkapp_DoOneEvent(PyObject *self, PyObject *args) int flags = 0; int rv; - if (!self && Py_Py3kWarningFlag) { - if (PyErr_Warn(PyExc_DeprecationWarning, - "_tkinter.dooneevent is gone in 3.x") < 0) - return NULL; - } - if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags)) return NULL; @@ -2700,12 +2598,6 @@ static PyObject * Tkapp_Quit(PyObject *self, PyObject *args) { - if (!self && Py_Py3kWarningFlag) { - if (PyErr_Warn(PyExc_DeprecationWarning, - "_tkinter.quit is gone in 3.x") < 0) - return NULL; - } - if (!PyArg_ParseTuple(args, ":quit")) return NULL; @@ -2721,7 +2613,7 @@ Tkapp_InterpAddr(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, ":interpaddr")) return NULL; - return PyInt_FromLong((long)Tkapp_Interp(self)); + return PyLong_FromLong((long)Tkapp_Interp(self)); } static PyObject * @@ -2857,12 +2749,6 @@ Tkapp_Dealloc(PyObject *self) DisableEventHook(); } -static PyObject * -Tkapp_GetAttr(PyObject *self, char *name) -{ - return Py_FindMethod(Tkapp_methods, self, name); -} - static PyTypeObject Tkapp_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -2871,14 +2757,28 @@ static PyTypeObject Tkapp_Type = 0, /*tp_itemsize */ Tkapp_Dealloc, /*tp_dealloc */ 0, /*tp_print */ - Tkapp_GetAttr, /*tp_getattr */ + 0, /*tp_getattr */ 0, /*tp_setattr */ - 0, /*tp_compare */ + 0, /*tp_reserved */ 0, /*tp_repr */ 0, /*tp_as_number */ 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Tkapp_methods, /*tp_methods*/ }; @@ -3000,7 +2900,8 @@ static PyObject * Tkinter_Create(PyObject *self, PyObject *args) { char *screenName = NULL; - char *baseName = NULL; + char *baseName = NULL; /* XXX this is not used anymore; + try getting rid of it. */ char *className = NULL; int interactive = 0; int wantobjects = 0; @@ -3008,11 +2909,6 @@ Tkinter_Create(PyObject *self, PyObject *args) int sync = 0; /* pass -sync to wish */ char *use = NULL; /* pass -use to wish */ - baseName = strrchr(Py_GetProgramName(), '/'); - if (baseName != NULL) - baseName++; - else - baseName = Py_GetProgramName(); className = "Tk"; if (!PyArg_ParseTuple(args, "|zssiiiiz:create", @@ -3021,7 +2917,7 @@ Tkinter_Create(PyObject *self, PyObject *args) &sync, &use)) return NULL; - return (PyObject *) Tkapp_New(screenName, baseName, className, + return (PyObject *) Tkapp_New(screenName, className, interactive, wantobjects, wantTk, sync, use); } @@ -3053,7 +2949,7 @@ frames in an animation."; static PyObject * Tkinter_getbusywaitinterval(PyObject *self, PyObject *args) { - return PyInt_FromLong(Tkinter_busywaitinterval); + return PyLong_FromLong(Tkinter_busywaitinterval); } static char getbusywaitinterval_doc[] = @@ -3066,14 +2962,6 @@ static PyMethodDef moduleMethods[] = { {"_flatten", Tkinter_Flatten, METH_VARARGS}, {"create", Tkinter_Create, METH_VARARGS}, -#ifdef HAVE_CREATEFILEHANDLER - {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS}, - {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS}, -#endif - {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS}, - {"mainloop", Tkapp_MainLoop, METH_VARARGS}, - {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS}, - {"quit", Tkapp_Quit, METH_VARARGS}, {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS, setbusywaitinterval_doc}, {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval, @@ -3184,7 +3072,7 @@ DisableEventHook(void) static void ins_long(PyObject *d, char *name, long val) { - PyObject *v = PyInt_FromLong(val); + PyObject *v = PyLong_FromLong(val); if (v) { PyDict_SetItemString(d, name, v); Py_DECREF(v); @@ -3193,7 +3081,7 @@ ins_long(PyObject *d, char *name, long val) static void ins_string(PyObject *d, char *name, char *val) { - PyObject *v = PyString_FromString(val); + PyObject *v = PyUnicode_FromString(val); if (v) { PyDict_SetItemString(d, name, v); Py_DECREF(v); @@ -3201,20 +3089,33 @@ ins_string(PyObject *d, char *name, char *val) } +static struct PyModuleDef _tkintermodule = { + PyModuleDef_HEAD_INIT, + "_tkinter", + NULL, + -1, + moduleMethods, + NULL, + NULL, + NULL, + NULL +}; + PyMODINIT_FUNC -init_tkinter(void) +PyInit__tkinter(void) { - PyObject *m, *d; + PyObject *m, *d, *uexe, *cexe; - Py_TYPE(&Tkapp_Type) = &PyType_Type; + if (PyType_Ready(&Tkapp_Type) < 0) + return NULL; #ifdef WITH_THREAD tcl_lock = PyThread_allocate_lock(); #endif - m = Py_InitModule("_tkinter", moduleMethods); + m = PyModule_Create(&_tkintermodule); if (m == NULL) - return; + return NULL; d = PyModule_GetDict(m); Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); @@ -3234,7 +3135,10 @@ init_tkinter(void) PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type); - Py_TYPE(&Tktt_Type) = &PyType_Type; + if (PyType_Ready(&Tktt_Type) < 0) { + Py_DECREF(m); + return NULL; + } PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type); Py_TYPE(&PyTclObject_Type) = &PyType_Type; @@ -3257,10 +3161,19 @@ init_tkinter(void) /* This helps the dynamic loader; in Unicode aware Tcl versions it also helps Tcl find its encodings. */ - Tcl_FindExecutable(Py_GetProgramName()); + uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); + if (uexe) { + cexe = PyUnicode_EncodeFSDefault(uexe); + if (cexe) + Tcl_FindExecutable(PyBytes_AsString(cexe)); + Py_XDECREF(cexe); + Py_DECREF(uexe); + } - if (PyErr_Occurred()) - return; + if (PyErr_Occurred()) { + Py_DECREF(m); + return NULL; + } #if 0 /* This was not a good idea; through <Destroy> bindings, @@ -3268,5 +3181,5 @@ init_tkinter(void) interpreter and thread state have already been destroyed! */ Py_AtExit(Tcl_Finalize); #endif - + return m; } |