@@ -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;
@@ -291,8 +291,7 @@ int get_tcl(HMODULE hMod)
291291 if (TCL_CREATE_COMMAND == NULL ) { // Maybe not TCL module
292292 return 0 ;
293293 }
294- TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod,
295- " Tcl_AppendResult" );
294+ TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod, " Tcl_AppendResult" );
296295 return (TCL_APPEND_RESULT == NULL ) ? -1 : 1 ;
297296}
298297
@@ -306,20 +305,20 @@ int get_tk(HMODULE hMod)
306305 if (TK_MAIN_WINDOW == NULL ) { // Maybe not Tk module
307306 return 0 ;
308307 }
309- return ( // -1 if any remaining symbols are NULL
308+ return // -1 if any remaining symbols are NULL
310309 ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
311310 _dfunc (hMod, " Tk_FindPhoto" )) == NULL ) ||
312311 ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
313312 _dfunc (hMod, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
314313 ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
315- _dfunc (hMod, " Tk_PhotoBlank" )) == NULL ))
314+ _dfunc (hMod, " Tk_PhotoBlank" )) == NULL )
316315 ? -1 : 1 ;
317316}
318317
319- int load_tkinter_funcs (void )
318+ void load_tkinter_funcs (void )
320319{
321320 // Load TCL and Tk functions by searching all modules in current process.
322- // Return 0 for success, non-zero for failure.
321+ // Sets an error on failure.
323322
324323 HMODULE hMods[1024 ];
325324 HANDLE hProcess;
@@ -337,17 +336,17 @@ int load_tkinter_funcs(void)
337336 if (!found_tcl) {
338337 found_tcl = get_tcl (hMods[i]);
339338 if (found_tcl == -1 ) {
340- return 1 ;
339+ return ;
341340 }
342341 }
343342 if (!found_tk) {
344343 found_tk = get_tk (hMods[i]);
345344 if (found_tk == -1 ) {
346- return 1 ;
345+ return ;
347346 }
348347 }
349348 if (found_tcl && found_tk) {
350- return 0 ;
349+ return ;
351350 }
352351 }
353352 }
@@ -357,7 +356,7 @@ int load_tkinter_funcs(void)
357356 } else {
358357 PyErr_SetString (PyExc_RuntimeError, " Could not find Tk routines" );
359358 }
360- return 1 ;
359+ return ;
361360}
362361
363362#else // not Windows
@@ -367,16 +366,6 @@ int load_tkinter_funcs(void)
367366 * tkinter uses these symbols, and the symbols are therefore visible in the
368367 * tkinter dynamic library (module).
369368 */
370- // From module __file__ attribute to char *string for dlopen.
371- char *fname2char (PyObject *fname)
372- {
373- PyObject* bytes;
374- bytes = PyUnicode_EncodeFSDefault (fname);
375- if (bytes == NULL ) {
376- return NULL ;
377- }
378- return PyBytes_AsString (bytes);
379- }
380369
381370#include < dlfcn.h>
382371
@@ -391,8 +380,7 @@ void *_dfunc(void *lib_handle, const char *func_name)
391380 dlerror ();
392381 func = dlsym (lib_handle, func_name);
393382 if (func == NULL ) {
394- const char *error = dlerror ();
395- PyErr_SetString (PyExc_RuntimeError, error);
383+ PyErr_SetString (PyExc_RuntimeError, dlerror ());
396384 }
397385 return func;
398386}
@@ -401,7 +389,7 @@ int _func_loader(void *lib)
401389{
402390 // Fill global function pointers from dynamic lib.
403391 // Return 1 if any pointer is NULL, 0 otherwise.
404- return (
392+ return
405393 ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
406394 _dfunc (lib, " Tcl_CreateCommand" )) == NULL ) ||
407395 ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
@@ -413,75 +401,50 @@ int _func_loader(void *lib)
413401 ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
414402 _dfunc (lib, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
415403 ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
416- _dfunc (lib, " Tk_PhotoBlank" )) == NULL )) ;
404+ _dfunc (lib, " Tk_PhotoBlank" )) == NULL );
417405}
418406
419- int load_tkinter_funcs (void )
407+ void load_tkinter_funcs (void )
420408{
421409 // Load tkinter global funcs from tkinter compiled module.
422- // Return 0 for success, non-zero for failure.
423- int ret = -1 ;
410+ // Sets an error on failure.
424411 void *main_program, *tkinter_lib;
425- char *tkinter_libname ;
426- PyObject *pModule = NULL , *pSubmodule = NULL , *pString = NULL ;
412+ PyObject * module = NULL , *py_path = NULL , *py_path_b = NULL ;
413+ char *path ;
427414
428- // Try loading from the main program namespace first
415+ // Try loading from the main program namespace first.
429416 main_program = dlopen (NULL , RTLD_LAZY);
430417 if (_func_loader (main_program) == 0 ) {
431- return 0 ;
418+ goto exit ;
432419 }
433420 // Clear exception triggered when we didn't find symbols above.
434421 PyErr_Clear ();
435422
436- // Now try finding the tkinter compiled module
437- pModule = PyImport_ImportModule (" tkinter" );
438- if (pModule == NULL ) {
439- goto exit;
440- }
441- pSubmodule = PyObject_GetAttrString (pModule, " _tkinter" );
442- if (pSubmodule == NULL ) {
443- goto exit;
423+ // Handle PyPy first, as that import will correctly fail on CPython.
424+ module = PyImport_ImportModule (" _tkinter.tklib_cffi" ); // PyPy
425+ if (!module ) {
426+ PyErr_Clear ();
427+ module = PyImport_ImportModule (" _tkinter" ); // CPython
444428 }
445- pString = PyObject_GetAttrString (pSubmodule, " __file__" );
446- if (pString == NULL ) {
429+ if (!(module &&
430+ (py_path = PyObject_GetAttrString (module , " __file__" )) &&
431+ (py_path_b = PyUnicode_EncodeFSDefault (py_path)) &&
432+ (path = PyBytes_AsString (py_path_b)))) {
447433 goto exit;
448434 }
449- tkinter_libname = fname2char (pString);
450- if (tkinter_libname == NULL ) {
435+ tkinter_lib = dlopen (path, RTLD_LAZY);
436+ if (!tkinter_lib) {
437+ PyErr_SetString (PyExc_RuntimeError, dlerror ());
451438 goto exit;
452439 }
453- tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
454- if (tkinter_lib == NULL ) {
455- /* Perhaps it is a cffi module, like in PyPy? */
456- pString = PyObject_GetAttrString (pSubmodule, " tklib_cffi" );
457- if (pString == NULL ) {
458- goto fail;
459- }
460- pString = PyObject_GetAttrString (pString, " __file__" );
461- if (pString == NULL ) {
462- goto fail;
463- }
464- tkinter_libname = fname2char (pString);
465- if (tkinter_libname == NULL ) {
466- goto fail;
467- }
468- tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
469- }
470- if (tkinter_lib == NULL ) {
471- goto fail;
472- }
473- ret = _func_loader (tkinter_lib);
474- // dlclose probably safe because tkinter has been imported.
440+ _func_loader (tkinter_lib);
441+ // dlclose is safe because tkinter has been imported.
475442 dlclose (tkinter_lib);
476443 goto exit;
477- fail:
478- PyErr_SetString (PyExc_RuntimeError,
479- " Cannot dlopen tkinter module file" );
480444exit:
481- Py_XDECREF (pModule);
482- Py_XDECREF (pSubmodule);
483- Py_XDECREF (pString);
484- return ret;
445+ Py_XDECREF (module );
446+ Py_XDECREF (py_path);
447+ Py_XDECREF (py_path_b);
485448}
486449#endif // end not Windows
487450
@@ -491,9 +454,6 @@ static PyModuleDef _tkagg_module = {
491454
492455PyMODINIT_FUNC PyInit__tkagg (void )
493456{
494- PyObject *m;
495-
496- m = PyModule_Create (&_tkagg_module);
497-
498- return (load_tkinter_funcs () == 0 ) ? m : NULL ;
457+ load_tkinter_funcs ();
458+ return PyErr_Occurred () ? NULL : PyModule_Create (&_tkagg_module);
499459}
0 commit comments