@@ -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;
@@ -250,8 +250,7 @@ int get_tcl(HMODULE hMod)
250
250
if (TCL_CREATE_COMMAND == NULL ) { // Maybe not TCL module
251
251
return 0 ;
252
252
}
253
- TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod,
254
- " Tcl_AppendResult" );
253
+ TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod, " Tcl_AppendResult" );
255
254
return (TCL_APPEND_RESULT == NULL ) ? -1 : 1 ;
256
255
}
257
256
@@ -265,20 +264,20 @@ int get_tk(HMODULE hMod)
265
264
if (TK_MAIN_WINDOW == NULL ) { // Maybe not Tk module
266
265
return 0 ;
267
266
}
268
- return ( // -1 if any remaining symbols are NULL
267
+ return // -1 if any remaining symbols are NULL
269
268
((TK_FIND_PHOTO = (Tk_FindPhoto_t)
270
269
_dfunc (hMod, " Tk_FindPhoto" )) == NULL ) ||
271
270
((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
272
271
_dfunc (hMod, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
273
272
((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
274
- _dfunc (hMod, " Tk_PhotoBlank" )) == NULL ))
273
+ _dfunc (hMod, " Tk_PhotoBlank" )) == NULL )
275
274
? -1 : 1 ;
276
275
}
277
276
278
- int load_tkinter_funcs (void )
277
+ void load_tkinter_funcs (void )
279
278
{
280
279
// 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.
282
281
283
282
HMODULE hMods[1024 ];
284
283
HANDLE hProcess;
@@ -296,17 +295,17 @@ int load_tkinter_funcs(void)
296
295
if (!found_tcl) {
297
296
found_tcl = get_tcl (hMods[i]);
298
297
if (found_tcl == -1 ) {
299
- return 1 ;
298
+ return ;
300
299
}
301
300
}
302
301
if (!found_tk) {
303
302
found_tk = get_tk (hMods[i]);
304
303
if (found_tk == -1 ) {
305
- return 1 ;
304
+ return ;
306
305
}
307
306
}
308
307
if (found_tcl && found_tk) {
309
- return 0 ;
308
+ return ;
310
309
}
311
310
}
312
311
}
@@ -316,7 +315,7 @@ int load_tkinter_funcs(void)
316
315
} else {
317
316
PyErr_SetString (PyExc_RuntimeError, " Could not find Tk routines" );
318
317
}
319
- return 1 ;
318
+ return ;
320
319
}
321
320
322
321
#else // not Windows
@@ -326,16 +325,6 @@ int load_tkinter_funcs(void)
326
325
* tkinter uses these symbols, and the symbols are therefore visible in the
327
326
* tkinter dynamic library (module).
328
327
*/
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
- }
339
328
340
329
#include < dlfcn.h>
341
330
@@ -350,8 +339,7 @@ void *_dfunc(void *lib_handle, const char *func_name)
350
339
dlerror ();
351
340
func = dlsym (lib_handle, func_name);
352
341
if (func == NULL ) {
353
- const char *error = dlerror ();
354
- PyErr_SetString (PyExc_RuntimeError, error);
342
+ PyErr_SetString (PyExc_RuntimeError, dlerror ());
355
343
}
356
344
return func;
357
345
}
@@ -360,7 +348,7 @@ int _func_loader(void *lib)
360
348
{
361
349
// Fill global function pointers from dynamic lib.
362
350
// Return 1 if any pointer is NULL, 0 otherwise.
363
- return (
351
+ return
364
352
((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
365
353
_dfunc (lib, " Tcl_CreateCommand" )) == NULL ) ||
366
354
((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
@@ -372,86 +360,58 @@ int _func_loader(void *lib)
372
360
((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
373
361
_dfunc (lib, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
374
362
((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
375
- _dfunc (lib, " Tk_PhotoBlank" )) == NULL )) ;
363
+ _dfunc (lib, " Tk_PhotoBlank" )) == NULL );
376
364
}
377
365
378
- int load_tkinter_funcs (void )
366
+ void load_tkinter_funcs (void )
379
367
{
380
368
// 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.
383
370
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 ;
386
373
387
- // Try loading from the main program namespace first
374
+ // Try loading from the main program namespace first.
388
375
main_program = dlopen (NULL , RTLD_LAZY);
389
376
if (_func_loader (main_program) == 0 ) {
390
- return 0 ;
377
+ goto exit ;
391
378
}
392
379
// Clear exception triggered when we didn't find symbols above.
393
380
PyErr_Clear ();
394
381
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
403
387
}
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)))) {
406
392
goto exit ;
407
393
}
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 ());
410
397
goto exit ;
411
398
}
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.
434
401
dlclose (tkinter_lib);
435
402
goto exit ;
436
- fail:
437
- PyErr_SetString (PyExc_RuntimeError,
438
- " Cannot dlopen tkinter module file" );
439
403
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);
444
407
}
445
408
#endif // end not Windows
446
409
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 };
449
412
450
413
PyMODINIT_FUNC PyInit__tkagg (void )
451
414
{
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);
457
417
}
0 commit comments