Bug summary
When the callback of a SpanSelector raises an exception, the _eventpress attribute is not cleared, which leads to weird behaviors later on.
Code for reproduction
from pylab import *
top, bot = figure(layout="constrained", figsize=(6, 5)).subplots(2)
# the top selector's callback intentionally raises an exception.
sel_top = mpl.widgets.SpanSelector(top, lambda *args: 1/0, "horizontal")
sel_bot = mpl.widgets.SpanSelector(bot, print, "vertical")
show()
Actual outcome
Interact with the top spanselector (an exception is thrown when the mouse button is released -- this is normal). Then interact with the bottom one: now it appears as if you were also dragging the top selector at the same time.
Expected outcome
The top selector doesn't move when we interact with the bottom selector.
Additional information
Likely the correct fix involves wrapping the callback in a try... finally so that the cleanup that needs to be done (resetting _eventpress, etc.) occurs no matter what, but any exception still gets propagated out. I didn't really follow whether that needs to be done in release() or in _release(), though. Or maybe the release handler can start by doing all the necessary cleanup and call the callback at the very end.
Likely also worth checking whether similar issues occur with other widgets.
Operating system
macos
Matplotlib Version
3.12.0.dev569+g2153774ae
Matplotlib Backend
qtagg
Python version
3.14
Jupyter version
none
Installation
git checkout
Bug summary
When the callback of a SpanSelector raises an exception, the _eventpress attribute is not cleared, which leads to weird behaviors later on.
Code for reproduction
Actual outcome
Interact with the top spanselector (an exception is thrown when the mouse button is released -- this is normal). Then interact with the bottom one: now it appears as if you were also dragging the top selector at the same time.
Expected outcome
The top selector doesn't move when we interact with the bottom selector.
Additional information
Likely the correct fix involves wrapping the callback in a try... finally so that the cleanup that needs to be done (resetting _eventpress, etc.) occurs no matter what, but any exception still gets propagated out. I didn't really follow whether that needs to be done in
release()or in_release(), though. Or maybe the release handler can start by doing all the necessary cleanup and call the callback at the very end.Likely also worth checking whether similar issues occur with other widgets.
Operating system
macos
Matplotlib Version
3.12.0.dev569+g2153774ae
Matplotlib Backend
qtagg
Python version
3.14
Jupyter version
none
Installation
git checkout