Skip to content

Commit 74aa9ab

Browse files
FIX: Handle AxesWidget cleanup after failed init (matplotlib#30935)
* FIX: Handle AxesWidget cleanup after failed init * Apply code review suggestions * Update lib/matplotlib/tests/test_widgets.py Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> * Remove __del__ method * Remove AxesWidget.__del__ from widgets.pyi --------- Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
1 parent 2fb2fd2 commit 74aa9ab

3 files changed

Lines changed: 15 additions & 6 deletions

File tree

lib/matplotlib/tests/test_widgets.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,17 @@ def test_rectangle_resize_square_center_aspect(ax, use_data_coordinates):
517517
46.25, 133.75])
518518

519519

520+
def test_axeswidget_del_on_failed_init():
521+
"""
522+
Test that an unraisable exception is not created when initialization
523+
fails.
524+
"""
525+
# Pytest would fail the test if such an exception occurred.
526+
fig, ax = plt.subplots()
527+
with pytest.raises(TypeError, match="unexpected keyword argument 'undefined'"):
528+
widgets.Button(ax, undefined='bar')
529+
530+
520531
def test_ellipse(ax):
521532
"""For ellipse, test out the key modifiers"""
522533
tool = widgets.EllipseSelector(ax, grab_range=10, interactive=True)

lib/matplotlib/widgets.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import enum
1313
import functools
1414
import itertools
15+
import weakref
1516
from numbers import Integral, Number
1617

1718
from cycler import cycler
@@ -118,10 +119,6 @@ def __init__(self, ax):
118119
self._cids = []
119120
self._blit_background_id = None
120121

121-
def __del__(self):
122-
if self._blit_background_id is not None:
123-
self.canvas._release_blit_background_id(self._blit_background_id)
124-
125122
canvas = property(
126123
lambda self: getattr(self.ax.get_figure(root=True), 'canvas', None)
127124
)
@@ -162,7 +159,9 @@ def _save_blit_background(self, background):
162159
good enough for all existing widgets.
163160
"""
164161
if self._blit_background_id is None:
165-
self._blit_background_id = self.canvas._get_blit_background_id()
162+
bbid = self.canvas._get_blit_background_id()
163+
weakref.finalize(self, self.canvas._release_blit_background_id, bbid)
164+
self._blit_background_id = bbid
166165
self.canvas._blit_backgrounds[self._blit_background_id] = background
167166

168167
def _load_blit_background(self):

lib/matplotlib/widgets.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class Widget:
3535
class AxesWidget(Widget):
3636
ax: Axes
3737
def __init__(self, ax: Axes) -> None: ...
38-
def __del__(self) -> None: ...
3938
@property
4039
def canvas(self) -> FigureCanvasBase | None: ...
4140
def connect_event(self, event: Event, callback: Callable) -> None: ...

0 commit comments

Comments
 (0)