summaryrefslogtreecommitdiffstats
path: root/Modules/_tkinter.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_tkinter.c')
-rw-r--r--Modules/_tkinter.c1085
1 files changed, 687 insertions, 398 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index 52025bb..41ad5f9 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -9,8 +9,8 @@ Copyright (C) 1994 Steen Lumholt.
/* TCL/TK VERSION INFO:
- Only Tcl/Tk 8.3.1 and later are supported. Older versions are not
- supported. Use Python 2.6 or older if you cannot upgrade your
+ Only Tcl/Tk 8.4 and later are supported. Older versions are not
+ supported. Use Python 3.4 or older if you cannot upgrade your
Tcl/Tk libraries.
*/
@@ -21,6 +21,7 @@ Copyright (C) 1994 Steen Lumholt.
*/
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include <ctype.h>
@@ -36,13 +37,6 @@ Copyright (C) 1994 Steen Lumholt.
#define CHECK_SIZE(size, elemsize) \
((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
-/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
- making _tkinter correct for this API means to break earlier
- versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
- earlier versions. Once Tcl releases before 8.4 don't need to be supported
- anymore, this should go. */
-#define USE_COMPAT_CONST
-
/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
it always; if Tcl is not threaded, the thread functions in
Tcl are empty. */
@@ -58,15 +52,8 @@ Copyright (C) 1994 Steen Lumholt.
#include "tkinter.h"
-/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
-#ifndef CONST84_RETURN
-#define CONST84_RETURN
-#undef CONST
-#define CONST
-#endif
-
-#if TK_HEX_VERSION < 0x08030201
-#error "Tk older than 8.3.1 not supported"
+#if TK_HEX_VERSION < 0x08040200
+#error "Tk older than 8.4 not supported"
#endif
#if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \
@@ -114,7 +101,65 @@ Copyright (C) 1994 Steen Lumholt.
#ifdef MS_WINDOWS
#include <conio.h>
#define WAIT_FOR_STDIN
+
+static PyObject *
+_get_tcl_lib_path()
+{
+ static PyObject *tcl_library_path = NULL;
+ static int already_checked = 0;
+
+ if (already_checked == 0) {
+ PyObject *prefix;
+ struct stat stat_buf;
+ int stat_return_value;
+
+ prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
+ if (prefix == NULL) {
+ return NULL;
+ }
+
+ /* Check expected location for an installed Python first */
+ tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION);
+ if (tcl_library_path == NULL) {
+ return NULL;
+ }
+ tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path);
+ if (tcl_library_path == NULL) {
+ return NULL;
+ }
+ stat_return_value = _Py_stat(tcl_library_path, &stat_buf);
+ if (stat_return_value == -2) {
+ return NULL;
+ }
+ if (stat_return_value == -1) {
+ /* install location doesn't exist, reset errno and see if
+ we're a repository build */
+ errno = 0;
+#ifdef Py_TCLTK_DIR
+ tcl_library_path = PyUnicode_FromString(
+ Py_TCLTK_DIR "\\lib\\tcl" TCL_VERSION);
+ if (tcl_library_path == NULL) {
+ return NULL;
+ }
+ stat_return_value = _Py_stat(tcl_library_path, &stat_buf);
+ if (stat_return_value == -2) {
+ return NULL;
+ }
+ if (stat_return_value == -1) {
+ /* tcltkDir for a repository build doesn't exist either,
+ reset errno and leave Tcl to its own devices */
+ errno = 0;
+ tcl_library_path = NULL;
+ }
+#else
+ tcl_library_path = NULL;
#endif
+ }
+ already_checked = 1;
+ }
+ return tcl_library_path;
+}
+#endif /* MS_WINDOWS */
#ifdef WITH_THREAD
@@ -385,10 +430,10 @@ unicodeFromTclObj(Tcl_Obj *value)
static PyObject *
-Split(char *list)
+Split(const char *list)
{
int argc;
- char **argv;
+ const char **argv;
PyObject *v;
if (list == NULL) {
@@ -432,7 +477,7 @@ static PyObject *
SplitObj(PyObject *arg)
{
if (PyTuple_Check(arg)) {
- int i, size;
+ Py_ssize_t i, size;
PyObject *elem, *newelem, *result;
size = PyTuple_Size(arg);
@@ -448,7 +493,7 @@ SplitObj(PyObject *arg)
return NULL;
}
if (!result) {
- int k;
+ Py_ssize_t k;
if (newelem == elem) {
Py_DECREF(newelem);
continue;
@@ -468,9 +513,29 @@ SplitObj(PyObject *arg)
return result;
/* Fall through, returning arg. */
}
+ else if (PyList_Check(arg)) {
+ Py_ssize_t i, size;
+ PyObject *elem, *newelem, *result;
+
+ size = PyList_GET_SIZE(arg);
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ /* Recursively invoke SplitObj for all list items. */
+ for(i = 0; i < size; i++) {
+ elem = PyList_GET_ITEM(arg, i);
+ newelem = SplitObj(elem);
+ if (!newelem) {
+ Py_XDECREF(result);
+ return NULL;
+ }
+ PyTuple_SetItem(result, i, newelem);
+ }
+ return result;
+ }
else if (PyUnicode_Check(arg)) {
int argc;
- char **argv;
+ const char **argv;
char *list = PyUnicode_AsUTF8(arg);
if (list == NULL ||
@@ -485,7 +550,7 @@ SplitObj(PyObject *arg)
}
else if (PyBytes_Check(arg)) {
int argc;
- char **argv;
+ const char **argv;
char *list = PyBytes_AsString(arg);
if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
@@ -502,6 +567,14 @@ SplitObj(PyObject *arg)
}
+/*[clinic input]
+module _tkinter
+class _tkinter.tkapp "TkappObject *" "&Tkapp_Type_spec"
+class _tkinter.Tcl_Obj "PyTclObject *" "&PyTclObject_Type_spec"
+class _tkinter.tktimertoken "TkttObject *" "&Tktt_Type_spec"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b1ebf15c162ee229]*/
+
/**** Tkapp Object ****/
#ifndef WITH_APPINIT
@@ -552,8 +625,9 @@ static void EnableEventHook(void); /* Forward */
static void DisableEventHook(void); /* Forward */
static TkappObject *
-Tkapp_New(char *screenName, char *className,
- int interactive, int wantobjects, int wantTk, int sync, char *use)
+Tkapp_New(const char *screenName, const char *className,
+ int interactive, int wantobjects, int wantTk, int sync,
+ const char *use)
{
TkappObject *v;
char *argv0;
@@ -610,7 +684,7 @@ Tkapp_New(char *screenName, char *className,
Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
/* This is used to get the application class for Tk 4.1 and up */
- argv0 = (char*)attemptckalloc(strlen(className) + 1);
+ argv0 = (char*)PyMem_Malloc(strlen(className) + 1);
if (!argv0) {
PyErr_NoMemory();
Py_DECREF(v);
@@ -621,7 +695,7 @@ Tkapp_New(char *screenName, char *className,
if (Py_ISUPPER(Py_CHARMASK(argv0[0])))
argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0]));
Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
- ckfree(argv0);
+ PyMem_Free(argv0);
if (! wantTk) {
Tcl_SetVar(v->interp,
@@ -637,14 +711,14 @@ Tkapp_New(char *screenName, char *className,
/* some initial arguments need to be in argv */
if (sync || use) {
char *args;
- int len = 0;
+ Py_ssize_t len = 0;
if (sync)
len += sizeof "-sync";
if (use)
- len += strlen(use) + sizeof "-use ";
+ len += strlen(use) + sizeof "-use "; /* never overflows */
- args = (char*)attemptckalloc(len);
+ args = (char*)PyMem_Malloc(len);
if (!args) {
PyErr_NoMemory();
Py_DECREF(v);
@@ -662,8 +736,35 @@ Tkapp_New(char *screenName, char *className,
}
Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
- ckfree(args);
+ PyMem_Free(args);
+ }
+
+#ifdef MS_WINDOWS
+ {
+ PyObject *str_path;
+ PyObject *utf8_path;
+ DWORD ret;
+
+ ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0);
+ if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
+ str_path = _get_tcl_lib_path();
+ if (str_path == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (str_path != NULL) {
+ utf8_path = PyUnicode_AsUTF8String(str_path);
+ if (utf8_path == NULL) {
+ return NULL;
+ }
+ Tcl_SetVar(v->interp,
+ "tcl_library",
+ PyBytes_AsString(utf8_path),
+ TCL_GLOBAL_ONLY);
+ Py_DECREF(utf8_path);
+ }
+ }
}
+#endif
if (Tcl_AppInit(v->interp) != TCL_OK) {
PyObject *result = Tkinter_Error((PyObject *)v);
@@ -929,9 +1030,14 @@ AsObj(PyObject *value)
{
Tcl_Obj *result;
- if (PyBytes_Check(value))
+ if (PyBytes_Check(value)) {
+ if (PyBytes_GET_SIZE(value) >= INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
+ return NULL;
+ }
return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value),
- PyBytes_GET_SIZE(value));
+ (int)PyBytes_GET_SIZE(value));
+ }
if (PyBool_Check(value))
return Tcl_NewBooleanObj(PyObject_IsTrue(value));
@@ -970,24 +1076,28 @@ AsObj(PyObject *value)
if (PyFloat_Check(value))
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
- if (PyTuple_Check(value)) {
+ if (PyTuple_Check(value) || PyList_Check(value)) {
Tcl_Obj **argv;
Py_ssize_t size, i;
- size = PyTuple_Size(value);
+ size = PySequence_Fast_GET_SIZE(value);
if (size == 0)
return Tcl_NewListObj(0, NULL);
if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
- PyErr_SetString(PyExc_OverflowError, "tuple is too long");
+ PyErr_SetString(PyExc_OverflowError,
+ PyTuple_Check(value) ? "tuple is too long" :
+ "list is too long");
return NULL;
}
- argv = (Tcl_Obj **) attemptckalloc(((size_t)size) * sizeof(Tcl_Obj *));
- if(!argv)
- return 0;
+ argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *));
+ if (!argv) {
+ PyErr_NoMemory();
+ return NULL;
+ }
for (i = 0; i < size; i++)
- argv[i] = AsObj(PyTuple_GetItem(value,i));
- result = Tcl_NewListObj(PyTuple_Size(value), argv);
- ckfree(FREECAST argv);
+ argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i));
+ result = Tcl_NewListObj((int)size, argv);
+ PyMem_Free(argv);
return result;
}
@@ -1012,9 +1122,9 @@ AsObj(PyObject *value)
}
kind = PyUnicode_KIND(value);
if (kind == sizeof(Tcl_UniChar))
- return Tcl_NewUnicodeObj(inbuf, size);
+ return Tcl_NewUnicodeObj(inbuf, (int)size);
allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
- outbuf = (Tcl_UniChar*)attemptckalloc(allocsize);
+ outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize);
/* Else overflow occurred, and we take the next exit */
if (!outbuf) {
PyErr_NoMemory();
@@ -1031,14 +1141,14 @@ AsObj(PyObject *value)
"character U+%x is above the range "
"(U+0000-U+FFFF) allowed by Tcl",
ch);
- ckfree(FREECAST outbuf);
+ PyMem_Free(outbuf);
return NULL;
}
#endif
outbuf[i] = ch;
}
- result = Tcl_NewUnicodeObj(outbuf, size);
- ckfree(FREECAST outbuf);
+ result = Tcl_NewUnicodeObj(outbuf, (int)size);
+ PyMem_Free(outbuf);
return result;
}
@@ -1067,7 +1177,6 @@ fromBoolean(PyObject* tkapp, Tcl_Obj *value)
return PyBool_FromLong(boolValue);
}
-#ifdef TCL_WIDE_INT_TYPE
static PyObject*
fromWideIntObj(PyObject* tkapp, Tcl_Obj *value)
{
@@ -1084,7 +1193,6 @@ fromWideIntObj(PyObject* tkapp, Tcl_Obj *value)
}
return NULL;
}
-#endif
#ifdef HAVE_LIBTOMMAMTH
static PyObject*
@@ -1157,7 +1265,6 @@ FromObj(PyObject* tkapp, Tcl_Obj *value)
fall through to wideInt handling. */
}
-#ifdef TCL_WIDE_INT_TYPE
if (value->typePtr == app->IntType ||
value->typePtr == app->WideIntType) {
result = fromWideIntObj(tkapp, value);
@@ -1167,7 +1274,6 @@ FromObj(PyObject* tkapp, Tcl_Obj *value)
/* If there is an error in the wideInt conversion,
fall through to bignum handling. */
}
-#endif
#ifdef HAVE_LIBTOMMAMTH
if (value->typePtr == app->IntType ||
@@ -1258,7 +1364,7 @@ Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
for (i = 0; i < objc; i++)
Tcl_DecrRefCount(objv[i]);
if (objv != objStore)
- ckfree(FREECAST objv);
+ PyMem_Free(objv);
}
/* Convert Python objects to Tcl objects. This must happen in the
@@ -1272,7 +1378,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
if (args == NULL)
/* do nothing */;
- else if (!PyTuple_Check(args)) {
+ else if (!(PyTuple_Check(args) || PyList_Check(args))) {
objv[0] = AsObj(args);
if (objv[0] == 0)
goto finally;
@@ -1280,14 +1386,16 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
Tcl_IncrRefCount(objv[0]);
}
else {
- objc = PyTuple_Size(args);
+ objc = PySequence_Fast_GET_SIZE(args);
if (objc > ARGSZ) {
if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
- PyErr_SetString(PyExc_OverflowError, "tuple is too long");
+ PyErr_SetString(PyExc_OverflowError,
+ PyTuple_Check(args) ? "tuple is too long" :
+ "list is too long");
return NULL;
}
- objv = (Tcl_Obj **)attemptckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
+ objv = (Tcl_Obj **)PyMem_Malloc(((size_t)objc) * sizeof(Tcl_Obj *));
if (objv == NULL) {
PyErr_NoMemory();
objc = 0;
@@ -1296,7 +1404,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
}
for (i = 0; i < objc; i++) {
- PyObject *v = PyTuple_GetItem(args, i);
+ PyObject *v = PySequence_Fast_GET_ITEM(args, i);
if (v == Py_None) {
objc = i;
break;
@@ -1311,10 +1419,10 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
Tcl_IncrRefCount(objv[i]);
}
}
- *pobjc = objc;
+ *pobjc = (int)objc;
return objv;
finally:
- Tkapp_CallDeallocArgs(objv, objStore, objc);
+ Tkapp_CallDeallocArgs(objv, objStore, (int)objc);
return NULL;
}
@@ -1474,16 +1582,21 @@ Tkapp_Call(PyObject *selfptr, PyObject *args)
}
+/*[clinic input]
+_tkinter.tkapp.eval
+
+ script: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_Eval(PyObject *self, PyObject *args)
+_tkinter_tkapp_eval_impl(TkappObject *self, const char *script)
+/*[clinic end generated code: output=24b79831f700dea0 input=481484123a455f22]*/
{
- char *script;
PyObject *res = NULL;
int err;
- if (!PyArg_ParseTuple(args, "s:eval", &script))
- return NULL;
-
CHECK_STRING_LENGTH(script);
CHECK_TCL_APPARTMENT;
@@ -1491,23 +1604,28 @@ Tkapp_Eval(PyObject *self, PyObject *args)
err = Tcl_Eval(Tkapp_Interp(self), script);
ENTER_OVERLAP
if (err == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
res = unicodeFromTclString(Tkapp_Result(self));
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.evalfile
+
+ fileName: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_EvalFile(PyObject *self, PyObject *args)
+_tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName)
+/*[clinic end generated code: output=63be88dcee4f11d3 input=873ab707e5e947e1]*/
{
- char *fileName;
PyObject *res = NULL;
int err;
- if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
- return NULL;
-
CHECK_STRING_LENGTH(fileName);
CHECK_TCL_APPARTMENT;
@@ -1515,23 +1633,28 @@ Tkapp_EvalFile(PyObject *self, PyObject *args)
err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
ENTER_OVERLAP
if (err == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
res = unicodeFromTclString(Tkapp_Result(self));
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.record
+
+ script: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_Record(PyObject *self, PyObject *args)
+_tkinter_tkapp_record_impl(TkappObject *self, const char *script)
+/*[clinic end generated code: output=0ffe08a0061730df input=c0b0db5a21412cac]*/
{
- char *script;
PyObject *res = NULL;
int err;
- if (!PyArg_ParseTuple(args, "s:record", &script))
- return NULL;
-
CHECK_STRING_LENGTH(script);
CHECK_TCL_APPARTMENT;
@@ -1539,20 +1662,25 @@ Tkapp_Record(PyObject *self, PyObject *args)
err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
ENTER_OVERLAP
if (err == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
res = unicodeFromTclString(Tkapp_Result(self));
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.adderrinfo
+
+ msg: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
+_tkinter_tkapp_adderrinfo_impl(TkappObject *self, const char *msg)
+/*[clinic end generated code: output=0e222ee2050eb357 input=4971399317d4c136]*/
{
- char *msg;
-
- if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
- return NULL;
CHECK_STRING_LENGTH(msg);
CHECK_TCL_APPARTMENT;
@@ -1585,6 +1713,15 @@ typedef struct VarEvent {
} VarEvent;
#endif
+/*[python]
+
+class varname_converter(CConverter):
+ type = 'const char *'
+ converter = 'varname_converter'
+
+[python]*/
+/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
static int
varname_converter(PyObject *in, void *_out)
{
@@ -1596,8 +1733,8 @@ varname_converter(PyObject *in, void *_out)
return 0;
}
s = PyBytes_AsString(in);
- if (strlen(s) != PyBytes_Size(in)) {
- PyErr_SetString(PyExc_ValueError, "null byte in bytes object");
+ if (strlen(s) != (size_t)PyBytes_Size(in)) {
+ PyErr_SetString(PyExc_ValueError, "embedded null byte");
return 0;
}
*out = s;
@@ -1613,8 +1750,8 @@ varname_converter(PyObject *in, void *_out)
PyErr_SetString(PyExc_OverflowError, "string is too long");
return 0;
}
- if (strlen(s) != size) {
- PyErr_SetString(PyExc_ValueError, "null character in string");
+ if (strlen(s) != (size_t)size) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
return 0;
}
*out = s;
@@ -1667,7 +1804,6 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
#ifdef WITH_THREAD
TkappObject *self = (TkappObject*)selfptr;
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
- TkappObject *self = (TkappObject*)selfptr;
VarEvent *ev;
PyObject *res, *exc_type, *exc_val;
Tcl_Condition cond = NULL;
@@ -1862,31 +1998,39 @@ Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
/** Tcl to Python **/
+/*[clinic input]
+_tkinter.tkapp.getint
+
+ arg: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_GetInt(PyObject *self, PyObject *args)
+_tkinter_tkapp_getint(TkappObject *self, PyObject *arg)
+/*[clinic end generated code: output=88cf293fae307cfe input=034026997c5b91f8]*/
{
char *s;
-#if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH)
Tcl_Obj *value;
PyObject *result;
-#else
- int intValue;
-#endif
- if (PyTuple_Size(args) == 1) {
- PyObject* o = PyTuple_GetItem(args, 0);
- if (PyLong_Check(o)) {
- Py_INCREF(o);
- return o;
- }
+ if (PyLong_Check(arg)) {
+ Py_INCREF(arg);
+ return arg;
+ }
+
+ if (PyTclObject_Check(arg)) {
+ value = ((PyTclObject*)arg)->value;
+ Tcl_IncrRefCount(value);
+ }
+ else {
+ if (!PyArg_Parse(arg, "s:getint", &s))
+ return NULL;
+ CHECK_STRING_LENGTH(s);
+ value = Tcl_NewStringObj(s, -1);
+ if (value == NULL)
+ return Tkinter_Error((PyObject *)self);
}
- if (!PyArg_ParseTuple(args, "s:getint", &s))
- return NULL;
- CHECK_STRING_LENGTH(s);
-#if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH)
- value = Tcl_NewStringObj(s, -1);
- if (value == NULL)
- return Tkinter_Error(self);
/* Don't use Tcl_GetInt() because it returns ambiguous result for value
in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform).
@@ -1894,43 +2038,67 @@ Tkapp_GetInt(PyObject *self, PyObject *args)
value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform).
*/
#ifdef HAVE_LIBTOMMAMTH
- result = fromBignumObj(self, value);
+ result = fromBignumObj((PyObject *)self, value);
#else
- result = fromWideIntObj(self, value);
+ result = fromWideIntObj((PyObject *)self, value);
#endif
Tcl_DecrRefCount(value);
if (result != NULL || PyErr_Occurred())
return result;
-#else
- if (Tcl_GetInt(Tkapp_Interp(self), s, &intValue) == TCL_OK)
- return PyLong_FromLong(intValue);
-#endif
- return Tkinter_Error(self);
+ return Tkinter_Error((PyObject *)self);
}
+/*[clinic input]
+_tkinter.tkapp.getdouble
+
+ arg: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_GetDouble(PyObject *self, PyObject *args)
+_tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg)
+/*[clinic end generated code: output=c52b138bd8b956b9 input=22015729ce9ef7f8]*/
{
char *s;
double v;
- if (PyTuple_Size(args) == 1) {
- PyObject *o = PyTuple_GetItem(args, 0);
- if (PyFloat_Check(o)) {
- Py_INCREF(o);
- return o;
- }
+ if (PyFloat_Check(arg)) {
+ Py_INCREF(arg);
+ return arg;
}
- if (!PyArg_ParseTuple(args, "s:getdouble", &s))
+
+ if (PyNumber_Check(arg)) {
+ return PyNumber_Float(arg);
+ }
+
+ if (PyTclObject_Check(arg)) {
+ if (Tcl_GetDoubleFromObj(Tkapp_Interp(self),
+ ((PyTclObject*)arg)->value,
+ &v) == TCL_ERROR)
+ return Tkinter_Error((PyObject *)self);
+ return PyFloat_FromDouble(v);
+ }
+
+ if (!PyArg_Parse(arg, "s:getdouble", &s))
return NULL;
CHECK_STRING_LENGTH(s);
if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
- return Tkinter_Error(self);
- return Py_BuildValue("d", v);
+ return Tkinter_Error((PyObject *)self);
+ return PyFloat_FromDouble(v);
}
+/*[clinic input]
+_tkinter.tkapp.getboolean
+
+ arg: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_GetBoolean(PyObject *self, PyObject *arg)
+_tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg)
+/*[clinic end generated code: output=726a9ae445821d91 input=7f11248ef8f8776e]*/
{
char *s;
int v;
@@ -1943,7 +2111,7 @@ Tkapp_GetBoolean(PyObject *self, PyObject *arg)
if (Tcl_GetBooleanFromObj(Tkapp_Interp(self),
((PyTclObject*)arg)->value,
&v) == TCL_ERROR)
- return Tkinter_Error(self);
+ return Tkinter_Error((PyObject *)self);
return PyBool_FromLong(v);
}
@@ -1951,20 +2119,25 @@ Tkapp_GetBoolean(PyObject *self, PyObject *arg)
return NULL;
CHECK_STRING_LENGTH(s);
if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
- return Tkinter_Error(self);
+ return Tkinter_Error((PyObject *)self);
return PyBool_FromLong(v);
}
+/*[clinic input]
+_tkinter.tkapp.exprstring
+
+ s: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_ExprString(PyObject *self, PyObject *args)
+_tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s)
+/*[clinic end generated code: output=beda323d3ed0abb1 input=fa78f751afb2f21b]*/
{
- char *s;
PyObject *res = NULL;
int retval;
- if (!PyArg_ParseTuple(args, "s:exprstring", &s))
- return NULL;
-
CHECK_STRING_LENGTH(s);
CHECK_TCL_APPARTMENT;
@@ -1972,24 +2145,29 @@ Tkapp_ExprString(PyObject *self, PyObject *args)
retval = Tcl_ExprString(Tkapp_Interp(self), s);
ENTER_OVERLAP
if (retval == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
res = unicodeFromTclString(Tkapp_Result(self));
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.exprlong
+
+ s: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_ExprLong(PyObject *self, PyObject *args)
+_tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s)
+/*[clinic end generated code: output=5d6a46b63c6ebcf9 input=11bd7eee0c57b4dc]*/
{
- char *s;
PyObject *res = NULL;
int retval;
long v;
- if (!PyArg_ParseTuple(args, "s:exprlong", &s))
- return NULL;
-
CHECK_STRING_LENGTH(s);
CHECK_TCL_APPARTMENT;
@@ -1997,23 +2175,29 @@ Tkapp_ExprLong(PyObject *self, PyObject *args)
retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
ENTER_OVERLAP
if (retval == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
- res = Py_BuildValue("l", v);
+ res = PyLong_FromLong(v);
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.exprdouble
+
+ s: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_ExprDouble(PyObject *self, PyObject *args)
+_tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s)
+/*[clinic end generated code: output=ff78df1081ea4158 input=ff02bc11798832d5]*/
{
- char *s;
PyObject *res = NULL;
double v;
int retval;
- if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
- return NULL;
CHECK_STRING_LENGTH(s);
CHECK_TCL_APPARTMENT;
PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
@@ -2022,61 +2206,74 @@ Tkapp_ExprDouble(PyObject *self, PyObject *args)
ENTER_OVERLAP
PyFPE_END_PROTECT(retval)
if (retval == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
- res = Py_BuildValue("d", v);
+ res = PyFloat_FromDouble(v);
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.exprboolean
+
+ s: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_ExprBoolean(PyObject *self, PyObject *args)
+_tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s)
+/*[clinic end generated code: output=8b28038c22887311 input=c8c66022bdb8d5d3]*/
{
- char *s;
PyObject *res = NULL;
int retval;
int v;
- if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
- return NULL;
CHECK_STRING_LENGTH(s);
CHECK_TCL_APPARTMENT;
ENTER_TCL
retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
ENTER_OVERLAP
if (retval == TCL_ERROR)
- res = Tkinter_Error(self);
+ res = Tkinter_Error((PyObject *)self);
else
- res = Py_BuildValue("i", v);
+ res = PyLong_FromLong(v);
LEAVE_OVERLAP_TCL
return res;
}
+/*[clinic input]
+_tkinter.tkapp.splitlist
+
+ arg: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_SplitList(PyObject *self, PyObject *args)
+_tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg)
+/*[clinic end generated code: output=13b51d34386d36fb input=2b2e13351e3c0b53]*/
{
char *list;
int argc;
- char **argv;
- PyObject *arg, *v;
+ const char **argv;
+ PyObject *v;
int i;
- if (!PyArg_ParseTuple(args, "O:splitlist", &arg))
- return NULL;
if (PyTclObject_Check(arg)) {
int objc;
Tcl_Obj **objv;
if (Tcl_ListObjGetElements(Tkapp_Interp(self),
((PyTclObject*)arg)->value,
&objc, &objv) == TCL_ERROR) {
- return Tkinter_Error(self);
+ return Tkinter_Error((PyObject *)self);
}
if (!(v = PyTuple_New(objc)))
return NULL;
for (i = 0; i < objc; i++) {
- PyObject *s = FromObj(self, objv[i]);
+ PyObject *s = FromObj((PyObject*)self, objv[i]);
if (!s || PyTuple_SetItem(v, i, s)) {
Py_DECREF(v);
return NULL;
@@ -2088,15 +2285,18 @@ Tkapp_SplitList(PyObject *self, PyObject *args)
Py_INCREF(arg);
return arg;
}
+ if (PyList_Check(arg)) {
+ return PySequence_Tuple(arg);
+ }
- if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
+ if (!PyArg_Parse(arg, "et:splitlist", "utf-8", &list))
return NULL;
CHECK_STRING_LENGTH(list);
if (Tcl_SplitList(Tkapp_Interp(self), list,
&argc, &argv) == TCL_ERROR) {
PyMem_Free(list);
- return Tkinter_Error(self);
+ return Tkinter_Error((PyObject *)self);
}
if (!(v = PyTuple_New(argc)))
@@ -2117,14 +2317,21 @@ Tkapp_SplitList(PyObject *self, PyObject *args)
return v;
}
+/*[clinic input]
+_tkinter.tkapp.split
+
+ arg: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_Split(PyObject *self, PyObject *args)
+_tkinter_tkapp_split(TkappObject *self, PyObject *arg)
+/*[clinic end generated code: output=e08ad832363facfd input=a1c78349eacaa140]*/
{
- PyObject *arg, *v;
+ PyObject *v;
char *list;
- if (!PyArg_ParseTuple(args, "O:split", &arg))
- return NULL;
if (PyTclObject_Check(arg)) {
Tcl_Obj *value = ((PyTclObject*)arg)->value;
int objc;
@@ -2132,16 +2339,16 @@ Tkapp_Split(PyObject *self, PyObject *args)
int i;
if (Tcl_ListObjGetElements(Tkapp_Interp(self), value,
&objc, &objv) == TCL_ERROR) {
- return FromObj(self, value);
+ return FromObj((PyObject*)self, value);
}
if (objc == 0)
return PyUnicode_FromString("");
if (objc == 1)
- return FromObj(self, objv[0]);
+ return FromObj((PyObject*)self, objv[0]);
if (!(v = PyTuple_New(objc)))
return NULL;
for (i = 0; i < objc; i++) {
- PyObject *s = FromObj(self, objv[i]);
+ PyObject *s = FromObj((PyObject*)self, objv[i]);
if (!s || PyTuple_SetItem(v, i, s)) {
Py_DECREF(v);
return NULL;
@@ -2149,10 +2356,10 @@ Tkapp_Split(PyObject *self, PyObject *args)
}
return v;
}
- if (PyTuple_Check(arg))
+ if (PyTuple_Check(arg) || PyList_Check(arg))
return SplitObj(arg);
- if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
+ if (!PyArg_Parse(arg, "et:split", "utf-8", &list))
return NULL;
CHECK_STRING_LENGTH(list);
v = Split(list);
@@ -2183,7 +2390,7 @@ PythonCmd_Error(Tcl_Interp *interp)
* function or method.
*/
static int
-PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
+PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[])
{
PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
PyObject *func, *arg, *res;
@@ -2252,7 +2459,7 @@ TCL_DECLARE_MUTEX(command_mutex)
typedef struct CommandEvent{
Tcl_Event ev;
Tcl_Interp* interp;
- char *name;
+ const char *name;
int create;
int *status;
ClientData *data;
@@ -2275,18 +2482,25 @@ Tkapp_CommandProc(CommandEvent *ev, int flags)
}
#endif
+/*[clinic input]
+_tkinter.tkapp.createcommand
+
+ self: self(type="TkappObject *")
+ name: str
+ func: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
+_tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name,
+ PyObject *func)
+/*[clinic end generated code: output=2a1c79a4ee2af410 input=2bc2c046a0914234]*/
{
- TkappObject *self = (TkappObject*)selfptr;
PythonCmd_ClientData *data;
- char *cmdName;
- PyObject *func;
int err;
- if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
- return NULL;
- CHECK_STRING_LENGTH(cmdName);
+ CHECK_STRING_LENGTH(name);
if (!PyCallable_Check(func)) {
PyErr_SetString(PyExc_TypeError, "command not callable");
return NULL;
@@ -2303,7 +2517,7 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
return PyErr_NoMemory();
Py_INCREF(self);
Py_INCREF(func);
- data->self = selfptr;
+ data->self = (PyObject *) self;
data->func = func;
#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
@@ -2317,7 +2531,7 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
ev->interp = self->interp;
ev->create = 1;
- ev->name = cmdName;
+ ev->name = name;
ev->data = (ClientData)data;
ev->status = &err;
ev->done = &cond;
@@ -2329,7 +2543,7 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
{
ENTER_TCL
err = Tcl_CreateCommand(
- Tkapp_Interp(self), cmdName, PythonCmd,
+ Tkapp_Interp(self), name, PythonCmd,
(ClientData)data, PythonCmdDelete) == NULL;
LEAVE_TCL
}
@@ -2344,16 +2558,22 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
+/*[clinic input]
+_tkinter.tkapp.deletecommand
+
+ self: self(type="TkappObject *")
+ name: str
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
+_tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name)
+/*[clinic end generated code: output=a67e8cb5845e0d2d input=b6306468f10b219c]*/
{
- TkappObject *self = (TkappObject*)selfptr;
- char *cmdName;
int err;
- if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
- return NULL;
- CHECK_STRING_LENGTH(cmdName);
+ CHECK_STRING_LENGTH(name);
#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
@@ -2367,7 +2587,7 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
ev->interp = self->interp;
ev->create = 0;
- ev->name = cmdName;
+ ev->name = name;
ev->status = &err;
ev->done = &cond;
Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
@@ -2378,7 +2598,7 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
#endif
{
ENTER_TCL
- err = Tcl_DeleteCommand(self->interp, cmdName);
+ err = Tcl_DeleteCommand(self->interp, name);
LEAVE_TCL
}
if (err == -1) {
@@ -2459,17 +2679,23 @@ FileHandler(ClientData clientData, int mask)
LEAVE_PYTHON
}
+/*[clinic input]
+_tkinter.tkapp.createfilehandler
+
+ file: object
+ mask: int
+ func: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
- /* args is (file, mask, func) */
+_tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file,
+ int mask, PyObject *func)
+/*[clinic end generated code: output=f73ce82de801c353 input=84943a5286e47947]*/
{
FileHandler_ClientData *data;
- PyObject *file, *func;
- int mask, tfile;
-
- if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
- &file, &mask, &func))
- return NULL;
+ int tfile;
CHECK_TCL_APPARTMENT;
@@ -2492,15 +2718,20 @@ Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+/*[clinic input]
+_tkinter.tkapp.deletefilehandler
+
+ file: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
+_tkinter_tkapp_deletefilehandler(TkappObject *self, PyObject *file)
+/*[clinic end generated code: output=b53cc96ebf9476fd input=abbec19d66312e2a]*/
{
- PyObject *file;
int tfile;
- if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
- return NULL;
-
CHECK_TCL_APPARTMENT;
tfile = PyObject_AsFileDescriptor(file);
@@ -2528,14 +2759,20 @@ typedef struct {
PyObject *func;
} TkttObject;
+/*[clinic input]
+_tkinter.tktimertoken.deletetimerhandler
+
+ self: self(type="TkttObject *")
+
+[clinic start generated code]*/
+
static PyObject *
-Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
+_tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self)
+/*[clinic end generated code: output=bd7fe17f328cfa55 input=25ba5dd594e52084]*/
{
- TkttObject *v = (TkttObject *)self;
+ TkttObject *v = self;
PyObject *func = v->func;
- if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
- return NULL;
if (v->token != NULL) {
Tcl_DeleteTimerHandler(v->token);
v->token = NULL;
@@ -2548,12 +2785,6 @@ Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyMethodDef Tktt_methods[] =
-{
- {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
- {NULL, NULL}
-};
-
static TkttObject *
Tktt_New(PyObject *func)
{
@@ -2595,22 +2826,6 @@ Tktt_Repr(PyObject *self)
v->func == NULL ? ", handler deleted" : "");
}
-static PyType_Slot Tktt_Type_slots[] = {
- {Py_tp_dealloc, Tktt_Dealloc},
- {Py_tp_repr, Tktt_Repr},
- {Py_tp_methods, Tktt_methods},
- {0, 0}
-};
-
-static PyType_Spec Tktt_Type_spec = {
- "_tkinter.tktimertoken",
- sizeof(TkttObject),
- 0,
- Py_TPFLAGS_DEFAULT,
- Tktt_Type_slots,
-};
-
-
/** Timer Handler **/
static void
@@ -2641,16 +2856,22 @@ TimerHandler(ClientData clientData)
LEAVE_PYTHON
}
+/*[clinic input]
+_tkinter.tkapp.createtimerhandler
+
+ milliseconds: int
+ func: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
+_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds,
+ PyObject *func)
+/*[clinic end generated code: output=2da5959b9d031911 input=ba6729f32f0277a5]*/
{
- int milliseconds;
- PyObject *func;
TkttObject *v;
- if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
- &milliseconds, &func))
- return NULL;
if (!PyCallable_Check(func)) {
PyErr_SetString(PyExc_TypeError, "bad argument list");
return NULL;
@@ -2670,18 +2891,23 @@ Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
/** Event Loop **/
+/*[clinic input]
+_tkinter.tkapp.mainloop
+
+ self: self(type="TkappObject *")
+ threshold: int = 0
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
+_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold)
+/*[clinic end generated code: output=0ba8eabbe57841b0 input=ad57c9c1dd2b9470]*/
{
- int threshold = 0;
- TkappObject *self = (TkappObject*)selfptr;
#ifdef WITH_THREAD
PyThreadState *tstate = PyThreadState_Get();
#endif
- if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
- return NULL;
-
CHECK_TCL_APPARTMENT;
self->dispatching = 1;
@@ -2733,44 +2959,56 @@ Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
Py_RETURN_NONE;
}
+/*[clinic input]
+_tkinter.tkapp.dooneevent
+
+ flags: int = 0
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_DoOneEvent(PyObject *self, PyObject *args)
+_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags)
+/*[clinic end generated code: output=27c6b2aa464cac29 input=6542b928e364b793]*/
{
- int flags = 0;
int rv;
- if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
- return NULL;
-
ENTER_TCL
rv = Tcl_DoOneEvent(flags);
LEAVE_TCL
- return Py_BuildValue("i", rv);
+ return PyLong_FromLong(rv);
}
+/*[clinic input]
+_tkinter.tkapp.quit
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_Quit(PyObject *self, PyObject *args)
+_tkinter_tkapp_quit_impl(TkappObject *self)
+/*[clinic end generated code: output=7f21eeff481f754f input=e03020dc38aff23c]*/
{
-
- if (!PyArg_ParseTuple(args, ":quit"))
- return NULL;
-
quitMainLoop = 1;
Py_RETURN_NONE;
}
+/*[clinic input]
+_tkinter.tkapp.interpaddr
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_InterpAddr(PyObject *self, PyObject *args)
+_tkinter_tkapp_interpaddr_impl(TkappObject *self)
+/*[clinic end generated code: output=6caaae3273b3c95a input=2dd32cbddb55a111]*/
{
-
- if (!PyArg_ParseTuple(args, ":interpaddr"))
- return NULL;
-
return PyLong_FromVoidPtr(Tkapp_Interp(self));
}
+/*[clinic input]
+_tkinter.tkapp.loadtk
+[clinic start generated code]*/
+
static PyObject *
-Tkapp_TkInit(PyObject *self, PyObject *args)
+_tkinter_tkapp_loadtk_impl(TkappObject *self)
+/*[clinic end generated code: output=e9e10a954ce46d2a input=b5e82afedd6354f0]*/
{
Tcl_Interp *interp = Tkapp_Interp(self);
const char * _tk_exists = NULL;
@@ -2796,7 +3034,7 @@ Tkapp_TkInit(PyObject *self, PyObject *args)
if (err == TCL_ERROR) {
/* This sets an exception, but we cannot return right
away because we need to exit the overlap first. */
- Tkinter_Error(self);
+ Tkinter_Error((PyObject *)self);
} else {
_tk_exists = Tkapp_Result(self);
}
@@ -2831,57 +3069,21 @@ Tkapp_WantObjects(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyObject *
-Tkapp_WillDispatch(PyObject *self, PyObject *args)
-{
-
- ((TkappObject*)self)->dispatching = 1;
-
- Py_RETURN_NONE;
-}
+/*[clinic input]
+_tkinter.tkapp.willdispatch
+ self: self(type="TkappObject *")
-/**** Tkapp Method List ****/
+[clinic start generated code]*/
-static PyMethodDef Tkapp_methods[] =
+static PyObject *
+_tkinter_tkapp_willdispatch_impl(TkappObject *self)
+/*[clinic end generated code: output=0e3f46d244642155 input=2630699767808970]*/
{
- {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
- {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
- {"call", Tkapp_Call, METH_VARARGS},
- {"eval", Tkapp_Eval, METH_VARARGS},
- {"evalfile", Tkapp_EvalFile, METH_VARARGS},
- {"record", Tkapp_Record, METH_VARARGS},
- {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
- {"setvar", Tkapp_SetVar, METH_VARARGS},
- {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
- {"getvar", Tkapp_GetVar, METH_VARARGS},
- {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
- {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
- {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
- {"getint", Tkapp_GetInt, METH_VARARGS},
- {"getdouble", Tkapp_GetDouble, METH_VARARGS},
- {"getboolean", Tkapp_GetBoolean, METH_O},
- {"exprstring", Tkapp_ExprString, METH_VARARGS},
- {"exprlong", Tkapp_ExprLong, METH_VARARGS},
- {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
- {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
- {"splitlist", Tkapp_SplitList, METH_VARARGS},
- {"split", Tkapp_Split, METH_VARARGS},
- {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
- {"deletecommand", Tkapp_DeleteCommand, 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},
- {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
- {"loadtk", Tkapp_TkInit, METH_NOARGS},
- {NULL, NULL}
-};
+ self->dispatching = 1;
+ Py_RETURN_NONE;
+}
/**** Tkapp Type Methods ****/
@@ -2899,41 +3101,26 @@ Tkapp_Dealloc(PyObject *self)
DisableEventHook();
}
-static PyType_Slot Tkapp_Type_slots[] = {
- {Py_tp_dealloc, Tkapp_Dealloc},
- {Py_tp_methods, Tkapp_methods},
- {0, 0}
-};
-
-
-static PyType_Spec Tkapp_Type_spec = {
- "_tkinter.tkapp",
- sizeof(TkappObject),
- 0,
- Py_TPFLAGS_DEFAULT,
- Tkapp_Type_slots,
-};
-
/**** Tkinter Module ****/
typedef struct {
PyObject* tuple;
- int size; /* current size */
- int maxsize; /* allocated size */
+ Py_ssize_t size; /* current size */
+ Py_ssize_t maxsize; /* allocated size */
} FlattenContext;
static int
-_bump(FlattenContext* context, int size)
+_bump(FlattenContext* context, Py_ssize_t size)
{
/* expand tuple to hold (at least) size new items.
return true if successful, false if an exception was raised */
- int maxsize = context->maxsize * 2;
+ Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */
if (maxsize < context->size + size)
- maxsize = context->size + size;
+ maxsize = context->size + size; /* never overflows */
context->maxsize = maxsize;
@@ -2945,41 +3132,21 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
{
/* add tuple or list to argument tuple (recursively) */
- int i, size;
+ Py_ssize_t i, size;
if (depth > 1000) {
PyErr_SetString(PyExc_ValueError,
"nesting too deep in _flatten");
return 0;
- } else if (PyList_Check(item)) {
- size = PyList_GET_SIZE(item);
+ } else if (PyTuple_Check(item) || PyList_Check(item)) {
+ size = PySequence_Fast_GET_SIZE(item);
/* preallocate (assume no nesting) */
if (context->size + size > context->maxsize &&
!_bump(context, size))
return 0;
/* copy items to output tuple */
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GET_ITEM(item, i);
- if (PyList_Check(o) || PyTuple_Check(o)) {
- if (!_flatten1(context, o, depth + 1))
- return 0;
- } else if (o != Py_None) {
- if (context->size + 1 > context->maxsize &&
- !_bump(context, 1))
- return 0;
- Py_INCREF(o);
- PyTuple_SET_ITEM(context->tuple,
- context->size++, o);
- }
- }
- } else if (PyTuple_Check(item)) {
- /* same, for tuples */
- size = PyTuple_GET_SIZE(item);
- if (context->size + size > context->maxsize &&
- !_bump(context, size))
- return 0;
- for (i = 0; i < size; i++) {
- PyObject *o = PyTuple_GET_ITEM(item, i);
+ PyObject *o = PySequence_Fast_GET_ITEM(item, i);
if (PyList_Check(o) || PyTuple_Check(o)) {
if (!_flatten1(context, o, depth + 1))
return 0;
@@ -2999,14 +3166,19 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
return 1;
}
+/*[clinic input]
+_tkinter._flatten
+
+ item: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkinter_Flatten(PyObject* self, PyObject* args)
+_tkinter__flatten(PyModuleDef *module, PyObject *item)
+/*[clinic end generated code: output=9505049ec74c3480 input=6b9c12260aa1157f]*/
{
FlattenContext context;
- PyObject* item;
-
- if (!PyArg_ParseTuple(args, "O:_flatten", &item))
- return NULL;
context.maxsize = PySequence_Size(item);
if (context.maxsize < 0)
@@ -3029,26 +3201,33 @@ Tkinter_Flatten(PyObject* self, PyObject* args)
return context.tuple;
}
+/*[clinic input]
+_tkinter.create
+
+ screenName: str(accept={str, NoneType}) = NULL
+ baseName: str = NULL
+ className: str = "Tk"
+ interactive: int(c_default="0") = False
+ wantobjects: int(c_default="0") = False
+ wantTk: int(c_default="1") = True
+ if false, then Tk_Init() doesn't get called
+ sync: int(c_default="0") = False
+ if true, then pass -sync to wish
+ use: str(accept={str, NoneType}) = NULL
+ if not None, then pass -use to wish
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-Tkinter_Create(PyObject *self, PyObject *args)
-{
- char *screenName = NULL;
- char *baseName = NULL; /* XXX this is not used anymore;
- try getting rid of it. */
- char *className = NULL;
- int interactive = 0;
- int wantobjects = 0;
- int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
- int sync = 0; /* pass -sync to wish */
- char *use = NULL; /* pass -use to wish */
-
- className = "Tk";
-
- if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
- &screenName, &baseName, &className,
- &interactive, &wantobjects, &wantTk,
- &sync, &use))
- return NULL;
+_tkinter_create_impl(PyModuleDef *module, const char *screenName,
+ const char *baseName, const char *className,
+ int interactive, int wantobjects, int wantTk, int sync,
+ const char *use)
+/*[clinic end generated code: output=b8847800fc3b27eb input=0d522aad1cb0ca0e]*/
+{
+ /* XXX baseName is not used anymore;
+ * try getting rid of it. */
CHECK_STRING_LENGTH(screenName);
CHECK_STRING_LENGTH(baseName);
CHECK_STRING_LENGTH(className);
@@ -3059,12 +3238,21 @@ Tkinter_Create(PyObject *self, PyObject *args)
sync, use);
}
+/*[clinic input]
+_tkinter.setbusywaitinterval
+
+ new_val: int
+ /
+
+Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.
+
+It should be set to a divisor of the maximum time between frames in an animation.
+[clinic start generated code]*/
+
static PyObject *
-Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
+_tkinter_setbusywaitinterval_impl(PyModuleDef *module, int new_val)
+/*[clinic end generated code: output=0b9d7ef7940461ea input=deca1d6f9e6dae47]*/
{
- int new_val;
- if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
- return NULL;
if (new_val < 0) {
PyErr_SetString(PyExc_ValueError,
"busywaitinterval must be >= 0");
@@ -3074,34 +3262,103 @@ Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static char setbusywaitinterval_doc[] =
-"setbusywaitinterval(n) -> None\n\
-\n\
-Set the busy-wait interval in milliseconds between successive\n\
-calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
-It should be set to a divisor of the maximum time between\n\
-frames in an animation.";
+/*[clinic input]
+_tkinter.getbusywaitinterval -> int
-static PyObject *
-Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
+Return the current busy-wait interval between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.
+[clinic start generated code]*/
+
+static int
+_tkinter_getbusywaitinterval_impl(PyModuleDef *module)
+/*[clinic end generated code: output=9d09eee026e96971 input=a695878d2d576a84]*/
{
- return PyLong_FromLong(Tkinter_busywaitinterval);
+ return Tkinter_busywaitinterval;
}
-static char getbusywaitinterval_doc[] =
-"getbusywaitinterval() -> int\n\
-\n\
-Return the current busy-wait interval between successive\n\
-calls to Tcl_DoOneEvent in a threaded Python interpreter.";
+#include "clinic/_tkinter.c.h"
+
+static PyMethodDef Tktt_methods[] =
+{
+ _TKINTER_TKTIMERTOKEN_DELETETIMERHANDLER_METHODDEF
+ {NULL, NULL}
+};
+
+static PyType_Slot Tktt_Type_slots[] = {
+ {Py_tp_dealloc, Tktt_Dealloc},
+ {Py_tp_repr, Tktt_Repr},
+ {Py_tp_methods, Tktt_methods},
+ {0, 0}
+};
+
+static PyType_Spec Tktt_Type_spec = {
+ "_tkinter.tktimertoken",
+ sizeof(TkttObject),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ Tktt_Type_slots,
+};
+
+
+/**** Tkapp Method List ****/
+
+static PyMethodDef Tkapp_methods[] =
+{
+ _TKINTER_TKAPP_WILLDISPATCH_METHODDEF
+ {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
+ {"call", Tkapp_Call, METH_VARARGS},
+ _TKINTER_TKAPP_EVAL_METHODDEF
+ _TKINTER_TKAPP_EVALFILE_METHODDEF
+ _TKINTER_TKAPP_RECORD_METHODDEF
+ _TKINTER_TKAPP_ADDERRINFO_METHODDEF
+ {"setvar", Tkapp_SetVar, METH_VARARGS},
+ {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
+ {"getvar", Tkapp_GetVar, METH_VARARGS},
+ {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
+ {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
+ {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
+ _TKINTER_TKAPP_GETINT_METHODDEF
+ _TKINTER_TKAPP_GETDOUBLE_METHODDEF
+ _TKINTER_TKAPP_GETBOOLEAN_METHODDEF
+ _TKINTER_TKAPP_EXPRSTRING_METHODDEF
+ _TKINTER_TKAPP_EXPRLONG_METHODDEF
+ _TKINTER_TKAPP_EXPRDOUBLE_METHODDEF
+ _TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF
+ _TKINTER_TKAPP_SPLITLIST_METHODDEF
+ _TKINTER_TKAPP_SPLIT_METHODDEF
+ _TKINTER_TKAPP_CREATECOMMAND_METHODDEF
+ _TKINTER_TKAPP_DELETECOMMAND_METHODDEF
+ _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF
+ _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF
+ _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF
+ _TKINTER_TKAPP_MAINLOOP_METHODDEF
+ _TKINTER_TKAPP_DOONEEVENT_METHODDEF
+ _TKINTER_TKAPP_QUIT_METHODDEF
+ _TKINTER_TKAPP_INTERPADDR_METHODDEF
+ _TKINTER_TKAPP_LOADTK_METHODDEF
+ {NULL, NULL}
+};
+
+static PyType_Slot Tkapp_Type_slots[] = {
+ {Py_tp_dealloc, Tkapp_Dealloc},
+ {Py_tp_methods, Tkapp_methods},
+ {0, 0}
+};
+
+
+static PyType_Spec Tkapp_Type_spec = {
+ "_tkinter.tkapp",
+ sizeof(TkappObject),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ Tkapp_Type_slots,
+};
static PyMethodDef moduleMethods[] =
{
- {"_flatten", Tkinter_Flatten, METH_VARARGS},
- {"create", Tkinter_Create, METH_VARARGS},
- {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
- setbusywaitinterval_doc},
- {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
- METH_NOARGS, getbusywaitinterval_doc},
+ _TKINTER__FLATTEN_METHODDEF
+ _TKINTER_CREATE_METHODDEF
+ _TKINTER_SETBUSYWAITINTERVAL_METHODDEF
+ _TKINTER_GETBUSYWAITINTERVAL_METHODDEF
{NULL, NULL}
};
@@ -3345,8 +3602,40 @@ PyInit__tkinter(void)
uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
if (uexe) {
cexe = PyUnicode_EncodeFSDefault(uexe);
- if (cexe)
+ if (cexe) {
+#ifdef MS_WINDOWS
+ int set_var = 0;
+ PyObject *str_path;
+ wchar_t *wcs_path;
+ DWORD ret;
+
+ ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0);
+
+ if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
+ str_path = _get_tcl_lib_path();
+ if (str_path == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (str_path != NULL) {
+ wcs_path = PyUnicode_AsWideCharString(str_path, NULL);
+ if (wcs_path == NULL) {
+ return NULL;
+ }
+ SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path);
+ set_var = 1;
+ }
+ }
+
Tcl_FindExecutable(PyBytes_AsString(cexe));
+
+ if (set_var) {
+ SetEnvironmentVariableW(L"TCL_LIBRARY", NULL);
+ PyMem_Free(wcs_path);
+ }
+#else
+ Tcl_FindExecutable(PyBytes_AsString(cexe));
+#endif /* MS_WINDOWS */
+ }
Py_XDECREF(cexe);
Py_DECREF(uexe);
}