| Server IP : 35.80.110.71 / Your IP : 216.73.216.221 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ip-172-31-21-44 6.17.0-1019-aws #19~24.04.1-Ubuntu SMP Tue Jun 23 18:53:06 UTC 2026 x86_64 User : ubuntu ( 1000) PHP Version : 8.3.31 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/matplotlib/tests/ |
Upload File : |
import functools
import importlib
import os
import platform
import subprocess
import sys
import tempfile
import warnings
from PIL import Image
import pytest
import matplotlib
from matplotlib import _c_internal_utils
from matplotlib.backend_tools import ToolToggleBase
from matplotlib.testing import subprocess_run_helper
import matplotlib.pyplot as plt
_test_timeout = 60 # A reasonably safe value for slower architectures.
def _isolated_tk_test(success_count, func=None):
"""
A decorator to run *func* in a subprocess and assert that it prints
"success" *success_count* times and nothing on stderr.
TkAgg tests seem to have interactions between tests, so isolate each test
in a subprocess. See GH#18261
"""
if func is None:
return functools.partial(_isolated_tk_test, success_count)
if "MPL_TEST_ESCAPE_HATCH" in os.environ:
# set in subprocess_run_helper() below
return func
@pytest.mark.skipif(
not importlib.util.find_spec('tkinter'),
reason="missing tkinter"
)
@pytest.mark.skipif(
sys.platform == "linux" and not _c_internal_utils.display_is_valid(),
reason="$DISPLAY and $WAYLAND_DISPLAY are unset"
)
@functools.wraps(func)
def test_func():
# even if the package exists, may not actually be importable this can
# be the case on some CI systems.
pytest.importorskip('tkinter')
try:
proc = subprocess_run_helper(
func, timeout=_test_timeout, extra_env=dict(
MPLBACKEND="TkAgg", MPL_TEST_ESCAPE_HATCH="1"))
except subprocess.TimeoutExpired:
pytest.fail("Subprocess timed out")
except subprocess.CalledProcessError as e:
pytest.fail("Subprocess failed to test intended behavior\n"
+ str(e.stderr))
else:
# macOS may actually emit irrelevant errors about Accelerated
# OpenGL vs. software OpenGL, or some permission error on Azure, so
# suppress them.
# Asserting stderr first (and printing it on failure) should be
# more helpful for debugging that printing a failed success count.
ignored_lines = ["OpenGL", "CFMessagePort: bootstrap_register",
"/usr/include/servers/bootstrap_defs.h"]
assert not [line for line in proc.stderr.splitlines()
if all(msg not in line for msg in ignored_lines)]
assert proc.stdout.count("success") == success_count
return test_func
@_isolated_tk_test(success_count=6) # len(bad_boxes)
def test_blit():
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.backends.backend_tkagg # noqa
from matplotlib.backends import _tkagg
fig, ax = plt.subplots()
photoimage = fig.canvas._tkphoto
data = np.ones((4, 4, 4))
height, width = data.shape[:2]
dataptr = (height, width, data.ctypes.data)
# Test out of bounds blitting.
bad_boxes = ((-1, 2, 0, 2),
(2, 0, 0, 2),
(1, 6, 0, 2),
(0, 2, -1, 2),
(0, 2, 2, 0),
(0, 2, 1, 6))
for bad_box in bad_boxes:
try:
_tkagg.blit(
photoimage.tk.interpaddr(), str(photoimage), dataptr, 0,
(0, 1, 2, 3), bad_box)
except ValueError:
print("success")
@_isolated_tk_test(success_count=1)
def test_figuremanager_preserves_host_mainloop():
import tkinter
import matplotlib.pyplot as plt
success = []
def do_plot():
plt.figure()
plt.plot([1, 2], [3, 5])
plt.close()
root.after(0, legitimate_quit)
def legitimate_quit():
root.quit()
success.append(True)
root = tkinter.Tk()
root.after(0, do_plot)
root.mainloop()
if success:
print("success")
@pytest.mark.skipif(platform.python_implementation() != 'CPython',
reason='PyPy does not support Tkinter threading: '
'https://foss.heptapod.net/pypy/pypy/-/issues/1929')
@pytest.mark.flaky(reruns=3)
@_isolated_tk_test(success_count=1)
def test_figuremanager_cleans_own_mainloop():
import tkinter
import time
import matplotlib.pyplot as plt
import threading
from matplotlib.cbook import _get_running_interactive_framework
root = tkinter.Tk()
plt.plot([1, 2, 3], [1, 2, 5])
def target():
while not 'tk' == _get_running_interactive_framework():
time.sleep(.01)
plt.close()
if show_finished_event.wait():
print('success')
show_finished_event = threading.Event()
thread = threading.Thread(target=target, daemon=True)
thread.start()
plt.show(block=True) # Testing if this function hangs.
show_finished_event.set()
thread.join()
@pytest.mark.backend('TkAgg', skip_on_importerror=True)
@pytest.mark.flaky(reruns=3)
@_isolated_tk_test(success_count=0)
def test_never_update():
import tkinter
del tkinter.Misc.update
del tkinter.Misc.update_idletasks
import matplotlib.pyplot as plt
fig = plt.figure()
plt.show(block=False)
plt.draw() # Test FigureCanvasTkAgg.
fig.canvas.toolbar.configure_subplots() # Test NavigationToolbar2Tk.
# Test FigureCanvasTk filter_destroy callback
fig.canvas.get_tk_widget().after(100, plt.close, fig)
# Check for update() or update_idletasks() in the event queue, functionally
# equivalent to tkinter.Misc.update.
plt.show(block=True)
# Note that exceptions would be printed to stderr; _isolated_tk_test
# checks them.
@pytest.mark.backend('TkAgg', skip_on_importerror=True)
@_isolated_tk_test(success_count=0)
def test_toolbar_button_la_mode_icon():
# test that icon in LA mode can be used for buttons
# see GH#25164
# tweaking toolbar raises an UserWarning
with warnings.catch_warnings():
warnings.simplefilter("ignore", UserWarning)
matplotlib.rcParams["toolbar"] = "toolmanager"
# create an icon in LA mode
with tempfile.TemporaryDirectory() as tempdir:
img = Image.new("LA", (26, 26))
tmp_img_path = os.path.join(tempdir, "test_la_icon.png")
img.save(tmp_img_path)
class CustomTool(ToolToggleBase):
image = tmp_img_path
fig = plt.figure()
toolmanager = fig.canvas.manager.toolmanager
toolbar = fig.canvas.manager.toolbar
toolmanager.add_tool("test", CustomTool)
toolbar.add_tool("test", "group")
@_isolated_tk_test(success_count=2)
def test_missing_back_button():
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk
class Toolbar(NavigationToolbar2Tk):
# Only display the buttons we need.
toolitems = [t for t in NavigationToolbar2Tk.toolitems if
t[0] in ('Home', 'Pan', 'Zoom')]
fig = plt.figure()
print("success")
Toolbar(fig.canvas, fig.canvas.manager.window) # This should not raise.
print("success")
@pytest.mark.backend('TkAgg', skip_on_importerror=True)
@_isolated_tk_test(success_count=1)
def test_canvas_focus():
import tkinter as tk
import matplotlib.pyplot as plt
success = []
def check_focus():
tkcanvas = fig.canvas.get_tk_widget()
# Give the plot window time to appear
if not tkcanvas.winfo_viewable():
tkcanvas.wait_visibility()
# Make sure the canvas has the focus, so that it's able to receive
# keyboard events.
if tkcanvas.focus_lastfor() == tkcanvas:
success.append(True)
plt.close()
root.destroy()
root = tk.Tk()
fig = plt.figure()
plt.plot([1, 2, 3])
root.after(0, plt.show)
root.after(100, check_focus)
root.mainloop()
if success:
print("success")
@_isolated_tk_test(success_count=2)
def test_embedding():
import tkinter as tk
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
root = tk.Tk()
def test_figure(master):
fig = Figure()
ax = fig.add_subplot()
ax.plot([1, 2, 3])
canvas = FigureCanvasTkAgg(fig, master=master)
canvas.draw()
canvas.mpl_connect("key_press_event", key_press_handler)
canvas.get_tk_widget().pack(expand=True, fill="both")
toolbar = NavigationToolbar2Tk(canvas, master, pack_toolbar=False)
toolbar.pack(expand=True, fill="x")
canvas.get_tk_widget().forget()
toolbar.forget()
test_figure(root)
print("success")
# Test with a dark button color. Doesn't actually check whether the icon
# color becomes lighter, just that the code doesn't break.
root.tk_setPalette(background="sky blue", selectColor="midnight blue",
foreground="white")
test_figure(root)
print("success")