Repository: matplotlib/matplotlib
File: lib/matplotlib/widgets.py (Python)

Code before:

    To guarantee that the widget remains responsive and not garbage-collected,
    a reference to the object should be maintained by the user.

    This is necessary because the callback registry
    maintains only weak-refs to the functions, which are member
    functions of the widget.  If there are no references to the widget
    object it may be garbage collected which will disconnect the callbacks.

    Attributes
    ----------
    ax : `~matplotlib.axes.Axes`
        The parent Axes for the widget.
    canvas : `~matplotlib.backend_bases.FigureCanvasBase`
        The parent figure canvas for the widget.
    active : bool
        If False, the widget does not respond to events.
    """

    def __init__(self, ax):
        self.ax = ax
        self._cids = []
        self._blit_background_id = None

    def __del__(self):
        blit_background_id = getattr(self, '_blit_background_id', None)
        if blit_background_id is not None:
            canvas = getattr(self, 'canvas', None)
            if canvas is not None:
                canvas._release_blit_background_id(blit_background_id)

    canvas = property(
        lambda self: getattr(self.ax.get_figure(root=True), 'canvas', None)
    )

    def connect_event(self, event, callback):
        """
        Connect a callback function with an event.

        This should be used in lieu of ``figure.canvas.mpl_connect`` since this
        function stores callback ids for later clean up.
        """
        cid = self.canvas.mpl_connect(event, callback)
        self._cids.append(cid)

    def disconnect_events(self):
        """Disconnect all events created by this widget."""
        for c in self._cids:
            self.canvas.mpl_disconnect(c)

    def ignore(self, event):

Review comment (suggestion):
```suggestion
        # __del__ may be called on a partially initialized object; e.g. when
        # __init__ raises. Therefore, we handle missing attributes gracefully.
        blit_background_id = getattr(self, '_blit_background_id', None)
```

Code after:
    Widget connected to a single `~matplotlib.axes.Axes`.

    To guarantee that the widget remains responsive and not garbage-collected,
    a reference to the object should be maintained by the user.

    This is necessary because the callback registry
    maintains only weak-refs to the functions, which are member
    functions of the widget.  If there are no references to the widget
    object it may be garbage collected which will disconnect the callbacks.

    Attributes
    ----------
    ax : `~matplotlib.axes.Axes`
        The parent Axes for the widget.
    canvas : `~matplotlib.backend_bases.FigureCanvasBase`
        The parent figure canvas for the widget.
    active : bool
        If False, the widget does not respond to events.
    """

    def __init__(self, ax):
        self.ax = ax
        self._cids = []
        self._blit_background_id = None

    canvas = property(
        lambda self: getattr(self.ax.get_figure(root=True), 'canvas', None)
    )

    def connect_event(self, event, callback):
        """
        Connect a callback function with an event.

        This should be used in lieu of ``figure.canvas.mpl_connect`` since this
        function stores callback ids for later clean up.
        """
        cid = self.canvas.mpl_connect(event, callback)
        self._cids.append(cid)

    def disconnect_events(self):
        """Disconnect all events created by this widget."""
        for c in self._cids:
            self.canvas.mpl_disconnect(c)

    def ignore(self, event):
        # docstring inherited
        return super().ignore(event) or self.canvas is None

    def _set_cursor(self, cursor):
        """Update the canvas cursor."""
        self.ax.get_figure(root=True).canvas.set_cursor(cursor)