enthought / traitsui

TraitsUI: Traits-capable windowing framework
http://docs.enthought.com/traitsui
Other
297 stars 96 forks source link

Editor error dialog yields 2 dialogs / subsequent segfault on MacOS and Pyqt5 #1550

Closed aaronayres35 closed 2 years ago

aaronayres35 commented 3 years ago

see PR #1546 for original inspiration.

To reproduce run:

from traits.api import HasTraits, Range

class Foo(HasTraits):
    x = Range(low=0.0, high=1.0, value=0.5, exclude_low=True)

Foo().configure_traits()

and drag the slider all the way to 0.0. Result is:

111837968-a77fba00-88c6-11eb-8f17-284309402c97

and closing the dialogs triggers a segfault

aaronayres35 commented 3 years ago

traceback after enabling faulthandler:

``` Fatal Python error: Segmentation fault Current thread 0x000000010febfe00 (most recent call first): File "/Users/aayres/Desktop/traitsui/traitsui/qt4/editor.py", line 90 in error File "/Users/aayres/Desktop/traitsui/traitsui/editor.py", line 756 in __set_value File "/Users/aayres/Desktop/traitsui/traitsui/ui.py", line 655 in do_undoable File "/Users/aayres/Desktop/traitsui/traitsui/editor.py", line 800 in _set_value File "/Users/aayres/Desktop/traitsui/traitsui/qt4/range_editor.py", line 63 in _set_value File "/Users/aayres/Desktop/traitsui/traitsui/qt4/range_editor.py", line 174 in update_object_on_scroll File "/Users/aayres/.edm/envs/traitsui-test-3.6-pyqt5/lib/python3.6/site-packages/pyface/util/guisupport.py", line 155 in start_event_loop_qt4 File "/Users/aayres/Desktop/traitsui/traitsui/qt4/view_application.py", line 141 in __init__ File "/Users/aayres/Desktop/traitsui/traitsui/qt4/view_application.py", line 94 in view_application File "/Users/aayres/Desktop/traitsui/traitsui/qt4/toolkit.py", line 243 in view_application File "/Users/aayres/.edm/envs/traitsui-test-3.6-pyqt5/lib/python3.6/site-packages/traits/has_traits.py", line 2095 in configure_traits File "traitsui/examples/demo/Standard_Editors/junk.py", line 9 in Segmentation fault: 11 ```

Code near end of traceback: https://github.com/enthought/traitsui/blob/75a694a82b455a0b29db481ad6b63cedc9d01c6d/traitsui/editor.py#L738-L757 Note that the error call does complete (I can see the output of a print statement after it but before raise). Commenting out the raise the segfault does not occur (at least immediately, but I am able to trigger one shortly after by clicking cancel and closing the new dialog. https://github.com/enthought/traitsui/blob/75a694a82b455a0b29db481ad6b63cedc9d01c6d/traitsui/qt4/editor.py#L72-L90

aaronayres35 commented 3 years ago

Okay so some how after adding a bunch of print statements the traceback now includes the following:

Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt.
You must not let any exception whatsoever propagate through Qt code.
If that is not possible, in Qt 5 you must at least reimplement
QCoreApplication::notify() and catch all exceptions there.

seems the exception is just slipping through the cracks

aaronayres35 commented 3 years ago

Note this can also be observed by changing the text to 0.0 and hitting enter.

I am confused by the 2 dialogs appearing, and print statements tell me that update_object_on_editor is being called twice. I believe it is being called based off a signal emitted by qt, based on this line: text.editingFinished.connect(self.update_object_on_enter) Perhaps the signal is getting emitted 2x? But also this is occurring with scroll

Shockingly, when scrolling to 0 I see that update_object_on_enter is called! This is resulting in the 2 dialogs in this case and I have a fix for it. The enter case is trickier... I believe what is happening is the first is triggered. Then the error dialog pops up as there is an invalid value. This dialog is modal, and steals the focus. Losing focus on the QLineEdit causes it to emit another editingFinished signal! (at least I think).

aaronayres35 commented 3 years ago

This looks like it may have been a duplicate of #158

1734 should close both issues I believe (would need to test #158 example code in issue description to be sure)