@@ -75,7 +75,7 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
75
75
}
76
76
/* get buffer from str which is "height width ptr" */
77
77
if (sscanf (argv[2 ], IMG_FORMAT, &hdata, &wdata, &pdata) != 3 ) {
78
- TCL_APPEND_RESULT (interp,
78
+ TCL_APPEND_RESULT (interp,
79
79
" error reading data, expected height width ptr" ,
80
80
(char *)NULL );
81
81
return TCL_ERROR;
@@ -291,8 +291,7 @@ int get_tcl(HMODULE hMod)
291
291
if (TCL_CREATE_COMMAND == NULL ) { // Maybe not TCL module
292
292
return 0 ;
293
293
}
294
- TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod,
295
- " Tcl_AppendResult" );
294
+ TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod, " Tcl_AppendResult" );
296
295
return (TCL_APPEND_RESULT == NULL ) ? -1 : 1 ;
297
296
}
298
297
@@ -306,20 +305,20 @@ int get_tk(HMODULE hMod)
306
305
if (TK_MAIN_WINDOW == NULL ) { // Maybe not Tk module
307
306
return 0 ;
308
307
}
309
- return ( // -1 if any remaining symbols are NULL
308
+ return // -1 if any remaining symbols are NULL
310
309
((TK_FIND_PHOTO = (Tk_FindPhoto_t)
311
310
_dfunc (hMod, " Tk_FindPhoto" )) == NULL ) ||
312
311
((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
313
312
_dfunc (hMod, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
314
313
((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
315
- _dfunc (hMod, " Tk_PhotoBlank" )) == NULL ))
314
+ _dfunc (hMod, " Tk_PhotoBlank" )) == NULL )
316
315
? -1 : 1 ;
317
316
}
318
317
319
- int load_tkinter_funcs (void )
318
+ void load_tkinter_funcs (void )
320
319
{
321
320
// 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.
323
322
324
323
HMODULE hMods[1024 ];
325
324
HANDLE hProcess;
@@ -337,17 +336,17 @@ int load_tkinter_funcs(void)
337
336
if (!found_tcl) {
338
337
found_tcl = get_tcl (hMods[i]);
339
338
if (found_tcl == -1 ) {
340
- return 1 ;
339
+ return ;
341
340
}
342
341
}
343
342
if (!found_tk) {
344
343
found_tk = get_tk (hMods[i]);
345
344
if (found_tk == -1 ) {
346
- return 1 ;
345
+ return ;
347
346
}
348
347
}
349
348
if (found_tcl && found_tk) {
350
- return 0 ;
349
+ return ;
351
350
}
352
351
}
353
352
}
@@ -357,7 +356,7 @@ int load_tkinter_funcs(void)
357
356
} else {
358
357
PyErr_SetString (PyExc_RuntimeError, " Could not find Tk routines" );
359
358
}
360
- return 1 ;
359
+ return ;
361
360
}
362
361
363
362
#else // not Windows
@@ -367,16 +366,6 @@ int load_tkinter_funcs(void)
367
366
* tkinter uses these symbols, and the symbols are therefore visible in the
368
367
* tkinter dynamic library (module).
369
368
*/
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
- }
380
369
381
370
#include < dlfcn.h>
382
371
@@ -391,8 +380,7 @@ void *_dfunc(void *lib_handle, const char *func_name)
391
380
dlerror ();
392
381
func = dlsym (lib_handle, func_name);
393
382
if (func == NULL ) {
394
- const char *error = dlerror ();
395
- PyErr_SetString (PyExc_RuntimeError, error);
383
+ PyErr_SetString (PyExc_RuntimeError, dlerror ());
396
384
}
397
385
return func;
398
386
}
@@ -401,7 +389,7 @@ int _func_loader(void *lib)
401
389
{
402
390
// Fill global function pointers from dynamic lib.
403
391
// Return 1 if any pointer is NULL, 0 otherwise.
404
- return (
392
+ return
405
393
((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
406
394
_dfunc (lib, " Tcl_CreateCommand" )) == NULL ) ||
407
395
((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
@@ -413,75 +401,50 @@ int _func_loader(void *lib)
413
401
((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
414
402
_dfunc (lib, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
415
403
((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
416
- _dfunc (lib, " Tk_PhotoBlank" )) == NULL )) ;
404
+ _dfunc (lib, " Tk_PhotoBlank" )) == NULL );
417
405
}
418
406
419
- int load_tkinter_funcs (void )
407
+ void load_tkinter_funcs (void )
420
408
{
421
409
// 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.
424
411
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 ;
427
414
428
- // Try loading from the main program namespace first
415
+ // Try loading from the main program namespace first.
429
416
main_program = dlopen (NULL , RTLD_LAZY);
430
417
if (_func_loader (main_program) == 0 ) {
431
- return 0 ;
418
+ goto exit ;
432
419
}
433
420
// Clear exception triggered when we didn't find symbols above.
434
421
PyErr_Clear ();
435
422
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
444
428
}
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)))) {
447
433
goto exit ;
448
434
}
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 ());
451
438
goto exit ;
452
439
}
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.
475
442
dlclose (tkinter_lib);
476
443
goto exit ;
477
- fail:
478
- PyErr_SetString (PyExc_RuntimeError,
479
- " Cannot dlopen tkinter module file" );
480
444
exit :
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);
485
448
}
486
449
#endif // end not Windows
487
450
@@ -491,9 +454,6 @@ static PyModuleDef _tkagg_module = {
491
454
492
455
PyMODINIT_FUNC PyInit__tkagg (void )
493
456
{
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);
499
459
}
0 commit comments