"runModalSession may not be invoked inside of transaction begin/commit pair"?

I’m trying to revive a ten(plus)-year-old project, and am having a problem I don’t know how to diagnose.

It’s a Mandelbrot explorer: https://nedbatchelder.com/code/aptus/, with latest code here: https://github.com/nedbat/aptus

Because the computation can be slow, I periodically get a bitmap from the computation code, and try to repaint the window. This used to work, ten years ago with wxPython 2.8 on Windows. Now I am using wxPython 4.1.0 on a Mac, and I get an error trace, and it doesn’t repaint until the computation is finished.

The stack trace is coming from here (https://github.com/nedbat/aptus/blob/56543233eee99c3da8fe127c3519c265bef23285/src/gui/computepanel.py#L172-L182):

    def draw_progress(self):
        """ Called from the GUI thread periodically during computation.
        
        Repaints the window.
        
        """
        self.bitmap = self.bitmap_from_compute()
        self.Refresh()
        self.Update()
        wx.CallAfter(self.fire_event, AptusRecomputedEvent)
        wx.SafeYield(onlyIfNeeded=True)

If I change wx.SafeYield to wx.GetApp().Yield(), there is no stack trace, but still nothing is repainted.

2020-07-04 12:24:31.838 Python[24634:18922618] -[NSApplication runModalSession:] may not be invoked inside of transaction begin/commit pair, or inside of transaction commit (usually this means it was invoked inside of a view's -drawRect: method.) The modal dialog has been suppressed to avoid deadlock. (
	0   AppKit                              0x00007fff5101fa59 -[NSApplication runModalSession:] + 187
	1   libwx_osx_cocoau_core-3.1.4.0.0.dylib 0x000000010d919ca0 _ZN14wxGUIEventLoop17DoDispatchTimeoutEm + 64
	2   libwx_baseu-3.1.4.0.0.dylib         0x000000010e119496 _ZN13wxCFEventLoop15DispatchTimeoutEm + 38
	3   libwx_baseu-3.1.4.0.0.dylib         0x000000010e1192eb _ZN13wxCFEventLoop10DoYieldForEl + 187
	4   libwx_baseu-3.1.4.0.0.dylib         0x000000010e05e115 _ZN15wxEventLoopBase8YieldForEl + 85
	5   libwx_osx_cocoau_core-3.1.4.0.0.dylib 0x000000010d85b297 _Z11wxSafeYieldP8wxWindowb + 55
	6   _core.so                            0x000000010cad91fe _ZL14func_SafeYieldP7_objectS0_S0_ + 126
	7   Python                              0x000000010bd4bbc3 PyEval_EvalFrameEx + 30323
	8   Python                              0x000000010bd50b22 fast_function + 274
	9   Python                              0x000000010bd4b744 PyEval_EvalFrameEx + 29172
	10  Python                              0x000000010bd50b22 fast_function + 274
	11  Python                              0x000000010bd4b744 PyEval_EvalFrameEx + 29172
	12  Python                              0x000000010bd50b22 fast_function + 274
	13  Python                              0x000000010bd4b744 PyEval_EvalFrameEx + 29172
	14  Python                              0x000000010bd44242 PyEval_EvalCodeEx + 1538
	15  Python                              0x000000010bcce68c function_call + 364
	16  Python                              0x000000010bca82a3 PyObject_Call + 99
	17  Python                              0x000000010bcb5666 instancemethod_call + 182
	18  Python                              0x000000010bca82a3 PyObject_Call + 99
	19  Python                              0x000000010bd501ed PyEval_CallObjectWithKeywords + 93
	20  _core.so                            0x000000010cbd0a4f _ZN12wxPyCallback12EventThunkerER7wxEvent + 271
	21  libwx_baseu-3.1.4.0.0.dylib         0x000000010e14613d _ZN12wxEvtHandler23SearchDynamicEventTableER7wxEvent + 317
	22  libwx_baseu-3.1.4.0.0.dylib         0x000000010e145e4b _ZN12wxEvtHandler19ProcessEventLocallyER7wxEvent + 59
	23  libwx_baseu-3.1.4.0.0.dylib         0x000000010e145d04 _ZN12wxEvtHandler12ProcessEventER7wxEvent + 100
	24  _core.so                            0x000000010cd3eaab _ZN10sipwxPanel12ProcessEventER7wxEvent + 107
	25  libwx_baseu-3.1.4.0.0.dylib         0x000000010e14643c _ZN12wxEvtHandler18SafelyProcessEventER7wxEvent + 12
	26  libwx_osx_cocoau_core-3.1.4.0.0.dylib 0x000000010d86d994 _ZN8wxWindow11MacDoRedrawEl + 676
	27  libwx_osx_cocoau_core-3.1.4.0.0.dylib 0x000000010d93d074 _ZN17wxWidgetCocoaImpl8drawRectEPvP6NSViewS0_ + 740
	28  libwx_osx_cocoau_core-3.1.4.0.0.dylib 0x000000010d93a306 _Z14wxOSX_drawRectP6NSViewP13objc_selector6CGRect + 86
	29  AppKit                              0x00007fff514b5f29 _NSViewDrawRect + 83
	30  AppKit                              0x00007fff50d4e73c -[NSView _drawRect:clip:] + 1819
	31  AppKit                              0x00007fff50d96b52 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 1735
	32  AppKit                              0x00007fff50d9701f -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2964
	33  AppKit                              0x00007fff50d4c656 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 938
	34  AppKit                              0x00007fff50d4cec5 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3097
	35  AppKit                              0x00007fff50d4bddb -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 327
	36  AppKit                              0x00007fff514b74e0 -[NSView _oldDisplayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 2051
	37  AppKit                              0x00007fff50d4ae5d -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 253
	38  AppKit                              0x00007fff50d470b4 -[NSView displayIfNeeded] + 1581
	39  AppKit                              0x00007fff50d46a52 -[NSWindow displayIfNeeded] + 321
	40  AppKit                              0x00007fff514e760d ___NSWindowGetDisplayCycleObserver_block_invoke.5902 + 308
	41  AppKit                              0x00007fff50d4655e __37+[NSDisplayCycle currentDisplayCycle]_block_invoke + 695
	42  QuartzCore                          0x00007fff5e9eb877 _ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase + 49
	43  QuartzCore                          0x00007fff5e9ea339 _ZN2CA11Transaction6commitEv + 171
	44  AppKit                              0x00007fff514fea72 __65+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayRefresh]_block_invoke + 283
	45  CoreFoundation                      0x00007fff5368e137 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
	46  CoreFoundation                      0x00007fff5368e05f __CFRunLoopDoObservers + 527
	47  CoreFoundation                      0x00007fff536705d8 __CFRunLoopRun + 1240
	48  CoreFoundation                      0x00007fff5366fe73 CFRunLoopRunSpecific + 483
	49  HIToolbox                           0x00007fff5295ad96 RunCurrentEventLoopInMode + 286
	50  HIToolbox                           0x00007fff5295ab06 ReceiveNextEventCommon + 613
	51  HIToolbox                           0x00007fff5295a884 _BlockUntilNextEventMatchingListInModeWithFilter + 64
	52  AppKit                              0x00007fff50c07a3b _DPSNextEvent + 2085
	53  AppKit                              0x00007fff5139de34 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 3044
	54  AppKit                              0x00007fff50bfc84d -[NSApplication run] + 764
	55  libwx_osx_cocoau_core-3.1.4.0.0.dylib 0x000000010d919eef _ZN14wxGUIEventLoop8OSXDoRunEv + 207
	56  libwx_baseu-3.1.4.0.0.dylib         0x000000010e119751 _ZN13wxCFEventLoop5DoRunEv + 49
	57  libwx_baseu-3.1.4.0.0.dylib         0x000000010e05df4e _ZN15wxEventLoopBase3RunEv + 158
	58  libwx_baseu-3.1.4.0.0.dylib         0x000000010e02ad43 _ZN16wxAppConsoleBase8MainLoopEv + 99
	59  _core.so                            0x000000010cd8df81 _ZN7wxPyApp8MainLoopEv + 81
	60  _core.so                            0x000000010cd90833 _ZL21meth_wxPyApp_MainLoopP7_objectS0_ + 147
	61  Python                              0x000000010bd4bb4e PyEval_EvalFrameEx + 30206
	62  Python                              0x000000010bd50b22 fast_function + 274
	63  Python                              0x000000010bd4b744 PyEval_EvalFrameEx + 29172
	64  Python                              0x000000010bd50b22 fast_function + 274
	65  Python                              0x000000010bd4b744 PyEval_EvalFrameEx + 29172
	66  Python                              0x000000010bd44242 PyEval_EvalCodeEx + 1538
	67  Python                              0x000000010bd43c36 PyEval_EvalCode + 54
	68  Python                              0x000000010bd73214 PyRun_FileExFlags + 164
	69  Python                              0x000000010bd72d91 PyRun_SimpleFileExFlags + 769
	70  Python                              0x000000010bd885b8 Py_Main + 3096
	71  libdyld.dylib                       0x00007fff7b5bc015 start + 1
)

The error message talks about a modal dialog, but I can’t think of what modal is trying to display during repainting?

This is on Python 2.7. I am going to be upgrading to 3.8, but thought I would fix this first. If upgrading would help, I can do that first.

How can I further diagnose this? I know the code is too complex for someone here to give me a fix, but maybe some common wisdom about how to proceed? Thanks.

Can you reproduce the problem in a smaller app?

I will try to do that. I was hoping something in the traceback would be a clue to a more experienced eye. :slight_smile: