Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b59a89e

Browse filesBrowse files
inspect running framework to decide if destroy should be delayed
1 parent 2056ce1 commit b59a89e
Copy full SHA for b59a89e

File tree

Expand file treeCollapse file tree

3 files changed

+18
-15
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+18
-15
lines changed

‎lib/matplotlib/backends/_backend_tk.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/_backend_tk.py
+10-6Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,18 +474,22 @@ def destroy(self, *args):
474474
self.canvas._tkcanvas.after_cancel(self.canvas._event_loop_id)
475475

476476
# NOTE: events need to be flushed before issuing destroy (GH #9956),
477-
# however, self.window.update() can break user code. This is the
478-
# safest way to achieve a complete draining of the event queue,
479-
# but it may require users to update() on their own to execute the
480-
# completion in obscure corner cases.
477+
# however, self.window.update() can break user code. An async callback
478+
# is the safest way to achieve a complete draining of the event queue,
479+
# but it leaks if no tk event loop is running. Therefore we explicitly
480+
# check for an event loop and choose our best guess.
481481
def delayed_destroy():
482482
self.window.destroy()
483483

484484
if self._owns_mainloop and not Gcf.get_num_fig_managers():
485485
self.window.quit()
486486

487-
# "after idle after 0" avoids Tcl error/race (GH #19940)
488-
self.window.after_idle(self.window.after, 0, delayed_destroy)
487+
if cbook._get_running_interactive_framework() == "tk":
488+
# "after idle after 0" avoids Tcl error/race (GH #19940)
489+
self.window.after_idle(self.window.after, 0, delayed_destroy)
490+
else:
491+
self.window.update()
492+
delayed_destroy()
489493

490494
def get_window_title(self):
491495
return self.window.wm_title()

‎lib/matplotlib/tests/test_backend_tk.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backend_tk.py
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ def test_func():
5050
)
5151
except subprocess.TimeoutExpired:
5252
pytest.fail("Subprocess timed out")
53-
except subprocess.CalledProcessError:
54-
pytest.fail("Subprocess failed to test intended behavior")
53+
except subprocess.CalledProcessError as e:
54+
pytest.fail("Subprocess failed to test intended behavior\n"
55+
+ str(e.stderr))
5556
else:
5657
# macOS may actually emit irrelevant errors about Accelerated
5758
# OpenGL vs. software OpenGL, so suppress them.
@@ -146,6 +147,7 @@ def target():
146147
thread.join()
147148

148149

150+
@pytest.mark.backend('TkAgg', skip_on_importerror=True)
149151
@pytest.mark.flaky(reruns=3)
150152
@_isolated_tk_test(success_count=0)
151153
def test_never_update():
@@ -159,14 +161,12 @@ def test_never_update():
159161

160162
plt.draw() # Test FigureCanvasTkAgg.
161163
fig.canvas.toolbar.configure_subplots() # Test NavigationToolbar2Tk.
164+
# Test FigureCanvasTk filter_destroy callback
165+
fig.canvas.get_tk_widget().after(100, plt.close, fig)
162166

163167
# Check for update() or update_idletasks() in the event queue, functionally
164168
# equivalent to tkinter.Misc.update.
165-
# Must pause >= 1 ms to process tcl idle events plus extra time to avoid
166-
# flaky tests on slow systems.
167-
plt.pause(0.1)
168-
169-
plt.close(fig) # Test FigureCanvasTk filter_destroy callback
169+
plt.show(block=True)
170170

171171
# Note that exceptions would be printed to stderr; _isolated_tk_test
172172
# checks them.

‎lib/matplotlib/tests/test_backends_interactive.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backends_interactive.py
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,7 @@ def _test_thread_impl():
195195
future = ThreadPoolExecutor().submit(fig.canvas.draw)
196196
plt.pause(0.5) # flush_events fails here on at least Tkagg (bpo-41176)
197197
future.result() # Joins the thread; rethrows any exception.
198-
plt.close()
199-
fig.canvas.flush_events() # pause doesn't process events after close
198+
plt.close() # backend is responsible for flushing any events here
200199

201200

202201
_thread_safe_backends = _get_testable_interactive_backends()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.