Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a4b16a3

Browse files
committed
Simplify tkagg C extension.
1 parent 5a8f4ea commit a4b16a3

File tree

1 file changed

+40
-80
lines changed

1 file changed

+40
-80
lines changed

src/_tkagg.cpp

Lines changed: 40 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
7575
}
7676
/* get buffer from str which is "height width ptr" */
7777
if (sscanf(argv[2], IMG_FORMAT, &hdata, &wdata, &pdata) != 3) {
78-
TCL_APPEND_RESULT(interp,
78+
TCL_APPEND_RESULT(interp,
7979
"error reading data, expected height width ptr",
8080
(char *)NULL);
8181
return TCL_ERROR;
@@ -250,8 +250,7 @@ int get_tcl(HMODULE hMod)
250250
if (TCL_CREATE_COMMAND == NULL) { // Maybe not TCL module
251251
return 0;
252252
}
253-
TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(hMod,
254-
"Tcl_AppendResult");
253+
TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(hMod, "Tcl_AppendResult");
255254
return (TCL_APPEND_RESULT == NULL) ? -1 : 1;
256255
}
257256

@@ -265,20 +264,20 @@ int get_tk(HMODULE hMod)
265264
if (TK_MAIN_WINDOW == NULL) { // Maybe not Tk module
266265
return 0;
267266
}
268-
return ( // -1 if any remaining symbols are NULL
267+
return // -1 if any remaining symbols are NULL
269268
((TK_FIND_PHOTO = (Tk_FindPhoto_t)
270269
_dfunc(hMod, "Tk_FindPhoto")) == NULL) ||
271270
((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
272271
_dfunc(hMod, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
273272
((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
274-
_dfunc(hMod, "Tk_PhotoBlank")) == NULL))
273+
_dfunc(hMod, "Tk_PhotoBlank")) == NULL)
275274
? -1 : 1;
276275
}
277276

278-
int load_tkinter_funcs(void)
277+
void load_tkinter_funcs(void)
279278
{
280279
// Load TCL and Tk functions by searching all modules in current process.
281-
// Return 0 for success, non-zero for failure.
280+
// Sets an error on failure.
282281

283282
HMODULE hMods[1024];
284283
HANDLE hProcess;
@@ -296,17 +295,17 @@ int load_tkinter_funcs(void)
296295
if (!found_tcl) {
297296
found_tcl = get_tcl(hMods[i]);
298297
if (found_tcl == -1) {
299-
return 1;
298+
return;
300299
}
301300
}
302301
if (!found_tk) {
303302
found_tk = get_tk(hMods[i]);
304303
if (found_tk == -1) {
305-
return 1;
304+
return;
306305
}
307306
}
308307
if (found_tcl && found_tk) {
309-
return 0;
308+
return;
310309
}
311310
}
312311
}
@@ -316,7 +315,7 @@ int load_tkinter_funcs(void)
316315
} else {
317316
PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines");
318317
}
319-
return 1;
318+
return;
320319
}
321320

322321
#else // not Windows
@@ -326,16 +325,6 @@ int load_tkinter_funcs(void)
326325
* tkinter uses these symbols, and the symbols are therefore visible in the
327326
* tkinter dynamic library (module).
328327
*/
329-
// From module __file__ attribute to char *string for dlopen.
330-
char *fname2char(PyObject *fname)
331-
{
332-
PyObject* bytes;
333-
bytes = PyUnicode_EncodeFSDefault(fname);
334-
if (bytes == NULL) {
335-
return NULL;
336-
}
337-
return PyBytes_AsString(bytes);
338-
}
339328

340329
#include <dlfcn.h>
341330

@@ -350,8 +339,7 @@ void *_dfunc(void *lib_handle, const char *func_name)
350339
dlerror();
351340
func = dlsym(lib_handle, func_name);
352341
if (func == NULL) {
353-
const char *error = dlerror();
354-
PyErr_SetString(PyExc_RuntimeError, error);
342+
PyErr_SetString(PyExc_RuntimeError, dlerror());
355343
}
356344
return func;
357345
}
@@ -360,7 +348,7 @@ int _func_loader(void *lib)
360348
{
361349
// Fill global function pointers from dynamic lib.
362350
// Return 1 if any pointer is NULL, 0 otherwise.
363-
return (
351+
return
364352
((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
365353
_dfunc(lib, "Tcl_CreateCommand")) == NULL) ||
366354
((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
@@ -372,86 +360,58 @@ int _func_loader(void *lib)
372360
((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
373361
_dfunc(lib, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
374362
((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
375-
_dfunc(lib, "Tk_PhotoBlank")) == NULL));
363+
_dfunc(lib, "Tk_PhotoBlank")) == NULL);
376364
}
377365

378-
int load_tkinter_funcs(void)
366+
void load_tkinter_funcs(void)
379367
{
380368
// Load tkinter global funcs from tkinter compiled module.
381-
// Return 0 for success, non-zero for failure.
382-
int ret = -1;
369+
// Sets an error on failure.
383370
void *main_program, *tkinter_lib;
384-
char *tkinter_libname;
385-
PyObject *pModule = NULL, *pSubmodule = NULL, *pString = NULL;
371+
PyObject *module = NULL, *py_path = NULL, *py_path_b = NULL;
372+
char *path;
386373

387-
// Try loading from the main program namespace first
374+
// Try loading from the main program namespace first.
388375
main_program = dlopen(NULL, RTLD_LAZY);
389376
if (_func_loader(main_program) == 0) {
390-
return 0;
377+
goto exit;
391378
}
392379
// Clear exception triggered when we didn't find symbols above.
393380
PyErr_Clear();
394381

395-
// Now try finding the tkinter compiled module
396-
pModule = PyImport_ImportModule("tkinter");
397-
if (pModule == NULL) {
398-
goto exit;
399-
}
400-
pSubmodule = PyObject_GetAttrString(pModule, "_tkinter");
401-
if (pSubmodule == NULL) {
402-
goto exit;
382+
// Handle PyPy first, as that import will correctly fail on CPython.
383+
module = PyImport_ImportModule("_tkinter.tklib_cffi"); // PyPy
384+
if (!module) {
385+
PyErr_Clear();
386+
module = PyImport_ImportModule("_tkinter"); // CPython
403387
}
404-
pString = PyObject_GetAttrString(pSubmodule, "__file__");
405-
if (pString == NULL) {
388+
if (!(module &&
389+
(py_path = PyObject_GetAttrString(module, "__file__")) &&
390+
(py_path_b = PyUnicode_EncodeFSDefault(py_path)) &&
391+
(path = PyBytes_AsString(py_path_b)))) {
406392
goto exit;
407393
}
408-
tkinter_libname = fname2char(pString);
409-
if (tkinter_libname == NULL) {
394+
tkinter_lib = dlopen(path, RTLD_LAZY);
395+
if (!tkinter_lib) {
396+
PyErr_SetString(PyExc_RuntimeError, dlerror());
410397
goto exit;
411398
}
412-
tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
413-
if (tkinter_lib == NULL) {
414-
/* Perhaps it is a cffi module, like in PyPy? */
415-
pString = PyObject_GetAttrString(pSubmodule, "tklib_cffi");
416-
if (pString == NULL) {
417-
goto fail;
418-
}
419-
pString = PyObject_GetAttrString(pString, "__file__");
420-
if (pString == NULL) {
421-
goto fail;
422-
}
423-
tkinter_libname = fname2char(pString);
424-
if (tkinter_libname == NULL) {
425-
goto fail;
426-
}
427-
tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
428-
}
429-
if (tkinter_lib == NULL) {
430-
goto fail;
431-
}
432-
ret = _func_loader(tkinter_lib);
433-
// dlclose probably safe because tkinter has been imported.
399+
_func_loader(tkinter_lib);
400+
// dlclose is safe because tkinter has been imported.
434401
dlclose(tkinter_lib);
435402
goto exit;
436-
fail:
437-
PyErr_SetString(PyExc_RuntimeError,
438-
"Cannot dlopen tkinter module file");
439403
exit:
440-
Py_XDECREF(pModule);
441-
Py_XDECREF(pSubmodule);
442-
Py_XDECREF(pString);
443-
return ret;
404+
Py_XDECREF(module);
405+
Py_XDECREF(py_path);
406+
Py_XDECREF(py_path_b);
444407
}
445408
#endif // end not Windows
446409

447-
static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions,
448-
NULL, NULL, NULL, NULL };
410+
static PyModuleDef _tkagg_module = {
411+
PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions, NULL, NULL, NULL, NULL };
449412

450413
PyMODINIT_FUNC PyInit__tkagg(void)
451414
{
452-
PyObject *m;
453-
454-
m = PyModule_Create(&_tkagg_module);
455-
456-
return (load_tkinter_funcs() == 0) ? m : NULL;
415+
load_tkinter_funcs();
416+
return PyErr_Occurred() ? NULL : PyModule_Create(&_tkagg_module);
457417
}

0 commit comments

Comments
 (0)