You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Python modules such as pyglet or pygame crash Python when tkinter message boxes are opened on MacOS. #90731
issue.py: A short test I put together showing the issue.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2022-02-03.21:05:49.571>created_at=<Date2022-01-29.18:48:13.856>labels= ['OS-mac', 'expert-tkinter', '3.10', 'type-crash']
title='Python modules such as pyglet or pygame crash Python when tkinter message boxes are opened on MacOS.'updated_at=<Date2022-02-03.21:05:49.570>user='https://bugs.python.org/remyrfouquette'
If I interpret the information I posted earlier correctly this is a bug in Tkinter, it calls a non-existing Objecive-C method (-[NSApplication macOSVersion]) and that results in an uncaught Objective-C exception and hence an abort().
BTW. All of this is using python 3.10.2 using the installer on python.org.
I've done some more research and this is an integration issue between pyglet and Tk. In particular:
Both pyglet and Tk use AppKit to implement their GUI
AppKit uses an NSApplication class, and in particular a singleton instance of that class, to represent the application, which will get instantiated during application startup
The Tk library uses a sublclass of NSApplication with additional functionality (TkApplication).
When pyglet is started first the NSApplication singleton is an instance of NSApplication and not of TkApplication, but Tk's implementation assumes that the singleton is an instance of TkApplicationo.
A workaround for this issue is to make sure Tk is initialised before initialising pyglet. For example using this code at the start of the script: "from tkinter import Tk; root = Tk()"
There's not much we can do about this in CPython, other than maybe filing an issue with the Tk project about this. I haven't looked at the Tk codebase and there cannot tell how hard it would be for then to avoid a dependency on TkApplication as a separate class (for example by implementing the additional functionality they need in a category on NSApplication).
Thanks for looking into this, Ronald. Before we close this as a Python issue, perhaps Marc might have a suggestion on what should be done here from a Tk perspective.
MarcCuller commented on Feb 2, 2022
MarcCullermannequin
Mannequin
More actions
The TKApplication class is a subclass of NSApplication which adds both
attributes and methods. Those are used throughout the macOS port of Tk,
and as Ronald says, the unique instance of NSApplication in Tk is actually
a TKApplication. Every macOS Application must have a unique NSApplication
object which is referenced by the global variable NSApp. The TKApplication
subclass was part of the first Cocoa port of Tk, long before I became
involved, and it may have even been there in the Carbon days. Subclassing
NSApplication appears to be something that Apple expects.
I don't know enough about Categories to understand how they could be used
to solve this problem. Do they somehow make it possible to add new methods
and attributes to an existing NSApplication object at runtime? I have
always thought of them as being syntactical in nature, as opposed to
allowing runtime modifications of an object's class after the object has
been instantiated. But I am not an expert on Categories by any means.
Thanks for looking into this, Ronald. Before we close this as a Python
issue, perhaps Marc might have a suggestion on what should be done here
from a Tk perspective.
Categories make it possible to add methods to an existing class, but not new attributes. The latter shouldn't be a problem in principle for an NSApplication subclass because only a single instance of the application class will get created and you may as well use global variables for those.
In some sense categories are syntactic sugar for monkey patching existing classes, commonly used to add convenience methods to Cocoa classes.
And thanks for bringing up the issue, Remy. Perhaps you can verify that Ronald's suggestion of importing and launching Tk before calling pyglet or pygame works for you and, if so, follow up with those projects to, if nothing else, document that requirement for their users on macOS (I would guess it wouldn't hurt on other platforms as well but I've guessed wrong before). In any case, I'm closing this issue now.
Something I forgot to mention: I don't think this is a bug in Tk now that I've looked into this more deeply.
The integration problem between Tk and other users of the Cocoa event loop is unfortunate but not a bug.
I do think that this is a bug in Tk, as this can be fixed in Tk simply by not subclassing NSApplication, and using categories and some global variables instead.
Activity
remyrfouquette commentedon Jan 29, 2022
The same problem doesn't exist on Windows.
ronaldoussoren commentedon Feb 1, 2022
Error output when running the script:
2022-02-01 22:15:32.213 Python[5468:5726153] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/d3/rc5nx4v12y96knh2px3bpqsc0000gn/T/org.python.python.savedState
2022-02-01 22:15:32.362 Python[5468:5726153] -[NSApplication macOSVersion]: unrecognized selector sent to instance 0x105624bc0
2022-02-01 22:15:32.367 Python[5468:5726153] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSApplication macOSVersion]: unrecognized selector sent to instance 0x105624bc0'
*** First throw call stack:
(
0 CoreFoundation 0x000000018b4c01cc __exceptionPreprocess + 240
1 libobjc.A.dylib 0x000000018b2117b8 objc_exception_throw + 60
2 CoreFoundation 0x000000018b5531a0 -[NSObject(NSObject) __retain_OA] + 0
3 CoreFoundation 0x000000018b420360 ___forwarding___ + 1728
4 CoreFoundation 0x000000018b41fbe0 _CF_forwarding_prep_0 + 96
5 libtk8.6.dylib 0x0000000100940a1c GetRGBA + 64
6 libtk8.6.dylib 0x00000001009404a8 SetCGColorComponents + 140
7 libtk8.6.dylib 0x00000001009408e0 TkpGetColor + 544
8 libtk8.6.dylib 0x00000001008a2454 Tk_GetColor + 220
9 libtk8.6.dylib 0x0000000100895aa0 Tk_Get3DBorder + 204
10 libtk8.6.dylib 0x00000001008958ac Tk_Alloc3DBorderFromObj + 144
11 libtk8.6.dylib 0x00000001008a3810 DoObjConfig + 832
12 libtk8.6.dylib 0x00000001008a33cc Tk_InitOptions + 348
13 libtk8.6.dylib 0x00000001008a32c8 Tk_InitOptions + 88
14 libtk8.6.dylib 0x00000001008cacf0 CreateFrame + 1448
15 libtk8.6.dylib 0x00000001008cafe8 TkListCreateFrame + 156
16 libtk8.6.dylib 0x00000001008c3ec0 Initialize + 1848
17 _tkinter.cpython-310-darwin.so 0x00000001008762d4 Tcl_AppInit + 92
18 _tkinter.cpython-310-darwin.so 0x0000000100875f6c Tkapp_New + 548
19 _tkinter.cpython-310-darwin.so 0x0000000100875d44 _tkinter_create_impl + 268
20 _tkinter.cpython-310-darwin.so 0x000000010087597c _tkinter_create + 240
21 Python 0x000000010109b1f0 cfunction_vectorcall_FASTCALL + 88
22 Python 0x0000000101169f48 call_function + 132
23 Python 0x0000000101161fac _PyEval_EvalFrameDefault + 23072
24 Python 0x000000010115ad5c _PyEval_Vector + 360
25 Python 0x0000000101033dac _PyObject_FastCallDictTstate + 96
26 Python 0x00000001010c7cbc slot_tp_init + 196
27 Python 0x00000001010be950 type_call + 312
28 Python 0x0000000101033af4 _PyObject_MakeTpCall + 136
29 Python 0x000000010116a040 call_function + 380
30 Python 0x0000000101160a18 _PyEval_EvalFrameDefault + 17548
31 Python 0x000000010115ad5c _PyEval_Vector + 360
32 Python 0x0000000101169f48 call_function + 132
33 Python 0x0000000101160a18 _PyEval_EvalFrameDefault + 17548
34 Python 0x000000010115ad5c _PyEval_Vector + 360
35 Python 0x0000000101169f48 call_function + 132
36 Python 0x0000000101161404 _PyEval_EvalFrameDefault + 20088
37 Python 0x000000010115ad5c _PyEval_Vector + 360
38 Python 0x000000010115cb3c _PyEval_EvalFrameDefault + 1456
39 Python 0x000000010115ad5c _PyEval_Vector + 360
40 Python 0x0000000101169f48 call_function + 132
41 Python 0x0000000101160a18 _PyEval_EvalFrameDefault + 17548
42 Python 0x000000010115ad5c _PyEval_Vector + 360
43 Python 0x000000010115cb3c _PyEval_EvalFrameDefault + 1456
44 Python 0x000000010115ad5c _PyEval_Vector + 360
45 Python 0x000000010115cb3c _PyEval_EvalFrameDefault + 1456
46 Python 0x000000010115ad5c _PyEval_Vector + 360
47 Python 0x0000000101169f48 call_function + 132
48 Python 0x0000000101161404 _PyEval_EvalFrameDefault + 20088
49 Python 0x000000010115ad5c _PyEval_Vector + 360
50 Python 0x0000000101169f48 call_function + 132
51 Python 0x0000000101161404 _PyEval_EvalFrameDefault + 20088
52 Python 0x000000010115ad5c _PyEval_Vector + 360
53 Python 0x0000000101169f48 call_function + 132
54 Python 0x0000000101161404 _PyEval_EvalFrameDefault + 20088
55 Python 0x000000010115ad5c _PyEval_Vector + 360
56 Python 0x0000000101169f48 call_function + 132
57 Python 0x0000000101161fac _PyEval_EvalFrameDefault + 23072
58 Python 0x000000010115ad5c _PyEval_Vector + 360
59 Python 0x00000001011c52c8 pyrun_file + 308
60 Python 0x00000001011c4a0c _PyRun_SimpleFileObject + 336
61 Python 0x00000001011c4058 _PyRun_AnyFileObject + 216
62 Python 0x00000001011f0280 pymain_run_file_obj + 180
63 Python 0x00000001011ef920 pymain_run_file + 72
64 Python 0x00000001011eef08 pymain_run_python + 300
65 Python 0x00000001011eed9c Py_RunMain + 24
66 Python 0x00000001011f0428 pymain_main + 56
67 Python 0x00000001011f06ec Py_BytesMain + 40
68 dyld 0x00000001005bd0f4 start + 520
)
libc++abi: terminating with uncaught exception of type NSException
ronaldoussoren commentedon Feb 1, 2022
The last bit of the call stack according to lldb:
frame #0: 0x000000018b3419b8 libsystem_kernel.dylib
__pthread_kill + 8 frame #1: 0x000000018b374eb0 libsystem_pthread.dylibpthread_kill + 288frame Rename README to README.rst and enhance formatting #2: 0x000000018b2b2314 libsystem_c.dylib
abort + 164 frame #3: 0x000000018b331b50 libc++abi.dylibabort_message + 132frame Update Python Software Foundation Copyright Year. #4: 0x000000018b322f64 libc++abi.dylib
demangling_terminate_handler() + 332 frame #5: 0x000000018b21a140 libobjc.A.dylib_objc_terminate() + 144frame Add Pycharm's .idea directory to gitignore #6: 0x000000018b330ee4 libc++abi.dylib`std::__terminate(void (*)()) + 20
__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 36 frame #8: 0x000000018b333c08 libc++abi.dylib__cxa_throw + 140frame Fix some deprecation warnings in Doc/conf.py #9: 0x000000018b2118dc libobjc.A.dylib
objc_exception_throw + 352 frame #10: 0x000000018b5531a0 CoreFoundation-[NSObject(NSObject) doesNotRecognizeSelector:] + 144frame bpo-29474: Improve documentation for weakref.WeakValueDictionary #11: 0x000000018b420360 CoreFoundation
___forwarding___ + 1728 frame #12: 0x000000018b41fbe0 CoreFoundation_CF_forwarding_prep_0 + 96frame Fix bpo-29528 Use a secure variable to stop spam #13: 0x0000000102388a1c libtk8.6.dylib
GetRGBA + 64 frame #14: 0x00000001023884a8 libtk8.6.dylibSetCGColorComponents + 140frame Use Sphinx 1.4.9 for now #15: 0x00000001023888e0 libtk8.6.dylib
TkpGetColor + 544 frame #16: 0x00000001022ea454 libtk8.6.dylibTk_GetColor + 220frame bpo-29438: fixed use-after-free in key sharing dict #17: 0x00000001022ddaa0 libtk8.6.dylib
Tk_Get3DBorder + 204 frame #18: 0x00000001022dd8ac libtk8.6.dylibTk_Alloc3DBorderFromObj + 144frame Rename Doc/README.txt to Doc/README.rst #19: 0x00000001022eb810 libtk8.6.dylib
DoObjConfig + 832 frame #20: 0x00000001022eb3cc libtk8.6.dylibTk_InitOptions + 348frame Update readme #21: 0x00000001022eb2c8 libtk8.6.dylib
Tk_InitOptions + 88 frame #22: 0x0000000102312cf0 libtk8.6.dylibCreateFrame + 1448frame [backport to 3.5] bpo-29474: Improve documentation for weakref.WeakValueDictionary #23: 0x0000000102312fe8 libtk8.6.dylib
TkListCreateFrame + 156 frame #24: 0x000000010230bec0 libtk8.6.dylibInitialize + 1848frame [backport to 3.6] bpo-29529: Add .travis.yml to 3.6 branch #25: 0x000000010026a2d4 _tkinter.cpython-310-darwin.so
Tcl_AppInit + 92 frame #26: 0x0000000100269f6c _tkinter.cpython-310-darwin.soTkapp_New + 548frame [backport to 2.7] bpo-29529: Add .travis.yml to 2.7 branch #27: 0x0000000100269d44 _tkinter.cpython-310-darwin.so
_tkinter_create_impl + 268 frame #28: 0x000000010026997c _tkinter.cpython-310-darwin.so_tkinter_create + 240frame Removing lengthy year numbers from Copyright #29: 0x0000000100bf71f0 Python`cfunction_vectorcall_FASTCALL + 88
ronaldoussoren commentedon Feb 1, 2022
If I interpret the information I posted earlier correctly this is a bug in Tkinter, it calls a non-existing Objecive-C method (
-[NSApplication macOSVersion]) and that results in an uncaught Objective-C exception and hence an abort().BTW. All of this is using python 3.10.2 using the installer on python.org.
ned-deily commentedon Feb 1, 2022
Tkinter? Or Tk itself?
ronaldoussoren commentedon Feb 2, 2022
Oops, sorry: In Tk itself.
ronaldoussoren commentedon Feb 2, 2022
I've done some more research and this is an integration issue between pyglet and Tk. In particular:
A workaround for this issue is to make sure Tk is initialised before initialising pyglet. For example using this code at the start of the script: "from tkinter import Tk; root = Tk()"
There's not much we can do about this in CPython, other than maybe filing an issue with the Tk project about this. I haven't looked at the Tk codebase and there cannot tell how hard it would be for then to avoid a dependency on TkApplication as a separate class (for example by implementing the additional functionality they need in a category on NSApplication).
ned-deily commentedon Feb 2, 2022
Thanks for looking into this, Ronald. Before we close this as a Python issue, perhaps Marc might have a suggestion on what should be done here from a Tk perspective.
MarcCuller commentedon Feb 2, 2022
The TKApplication class is a subclass of NSApplication which adds both
attributes and methods. Those are used throughout the macOS port of Tk,
and as Ronald says, the unique instance of NSApplication in Tk is actually
a TKApplication. Every macOS Application must have a unique NSApplication
object which is referenced by the global variable NSApp. The TKApplication
subclass was part of the first Cocoa port of Tk, long before I became
involved, and it may have even been there in the Carbon days. Subclassing
NSApplication appears to be something that Apple expects.
I don't know enough about Categories to understand how they could be used
to solve this problem. Do they somehow make it possible to add new methods
and attributes to an existing NSApplication object at runtime? I have
always thought of them as being syntactical in nature, as opposed to
allowing runtime modifications of an object's class after the object has
been instantiated. But I am not an expert on Categories by any means.
On Wed, Feb 2, 2022 at 1:54 PM Ned Deily <[email protected]> wrote:
ronaldoussoren commentedon Feb 3, 2022
Categories make it possible to add methods to an existing class, but not new attributes. The latter shouldn't be a problem in principle for an NSApplication subclass because only a single instance of the application class will get created and you may as well use global variables for those.
In some sense categories are syntactic sugar for monkey patching existing classes, commonly used to add convenience methods to Cocoa classes.
ronaldoussoren commentedon Feb 3, 2022
Something I forgot to mention: I don't think this is a bug in Tk now that I've looked into this more deeply.
The integration problem between Tk and other users of the Cocoa event loop is unfortunate but not a bug.
ned-deily commentedon Feb 3, 2022
Thanks, Marc and Ronald, for the analysis.
And thanks for bringing up the issue, Remy. Perhaps you can verify that Ronald's suggestion of importing and launching Tk before calling pyglet or pygame works for you and, if so, follow up with those projects to, if nothing else, document that requirement for their users on macOS (I would guess it wouldn't hurt on other platforms as well but I've guessed wrong before). In any case, I'm closing this issue now.
mdehoon commentedon Jun 4, 2026
@ronaldoussoren
I do think that this is a bug in Tk, as this can be fixed in Tk simply by not subclassing NSApplication, and using categories and some global variables instead.
See https://core.tcl-lang.org/tk/tktview/637e74c1e7 for a bug report in Tk.