From 9ddd37a2132fdc064d537f67f7a85d714abd84bb Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Tue, 7 Feb 2023 11:28:04 -0600 Subject: [PATCH] Backport PR #25097: fix FigureCanvasTkAgg memory leak via weakrefs --- lib/matplotlib/backends/_backend_tk.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index bdbbd6ad6c77..3199ff1e8083 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -1,4 +1,5 @@ import uuid +import weakref from contextlib import contextmanager import logging import math @@ -198,14 +199,33 @@ def __init__(self, figure=None, master=None): # event to the window containing the canvas instead. # See https://wiki.tcl-lang.org/3893 (mousewheel) for details root = self._tkcanvas.winfo_toplevel() - root.bind("", self.scroll_event_windows, "+") + + # Prevent long-lived references via tkinter callback structure GH-24820 + weakself = weakref.ref(self) + weakroot = weakref.ref(root) + + def scroll_event_windows(event): + self = weakself() + if self is None: + root = weakroot() + if root is not None: + root.unbind("", scroll_event_windows_id) + return + return self.scroll_event_windows(event) + scroll_event_windows_id = root.bind("", scroll_event_windows, "+") # Can't get destroy events by binding to _tkcanvas. Therefore, bind # to the window and filter. def filter_destroy(event): + self = weakself() + if self is None: + root = weakroot() + if root is not None: + root.unbind("", filter_destroy_id) + return if event.widget is self._tkcanvas: CloseEvent("close_event", self)._process() - root.bind("", filter_destroy, "+") + filter_destroy_id = root.bind("", filter_destroy, "+") self._tkcanvas.focus_set() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy