commit df72f3e63c93be7dbc519bccab7daf1871d704a8 Author: Victor Stinner Date: Tue Aug 8 14:28:17 2017 +0200 tooling diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk_guionly.py index 462665d..a52314c 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk_guionly.py @@ -30,5 +30,9 @@ def test_main(): support.run_unittest( *runtktests.get_tests(text=False, packages=['test_ttk'])) + support.gc_collect() + if ttk.Widget.INSTANCE > 0: + raise Exception("leaking %s ttk widgets" % ttk.Widget.INSTANCE) + if __name__ == '__main__': test_main() diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index deea791..88d8c9f 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -2300,6 +2300,9 @@ class BaseWidget(Misc): if self._name in self.master.children: del self.master.children[self._name] Misc.destroy(self) + if self.children: + raise Exception("destroy() doesn't clear all children: %s" + % self.children) def _do(self, name, args=()): # XXX Obsolete -- better use self.tk.call directly! return self.tk.call((self._w, name) + args) diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py index dd155fa..64ef992 100644 --- a/Lib/tkinter/test/support.py +++ b/Lib/tkinter/test/support.py @@ -22,6 +22,11 @@ class AbstractTkTest: @classmethod def tearDownClass(cls): cls.root.update_idletasks() + + widgets = cls.root.grid_slaves() + for widget in widgets: + widget.destroy() + cls.root.destroy() del cls.root tkinter._default_root = None diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index 3ecc004..1e23808 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -531,6 +531,7 @@ class Style(object): class Widget(tkinter.Widget): """Base class for Tk themed widgets.""" + INSTANCE = 0 def __init__(self, master, widgetname, kw=None): """Constructs a Ttk Widget with the parent master. @@ -557,6 +558,11 @@ class Widget(tkinter.Widget): # Load tile now, if needed _load_tile(master) tkinter.Widget.__init__(self, master, widgetname, kw=kw) + Widget.INSTANCE += 1 + + + def __del__(self): + Widget.INSTANCE -= 1 def identify(self, x, y):