diff --git a/doc/api/next_api_changes/removals/XXXXX-AL.rst b/doc/api/next_api_changes/removals/XXXXX-AL.rst new file mode 100644 index 000000000000..490519c2c650 --- /dev/null +++ b/doc/api/next_api_changes/removals/XXXXX-AL.rst @@ -0,0 +1,4 @@ +``backend_template.show`` +~~~~~~~~~~~~~~~~~~~~~~~~~ +... has been removed, in order to better demonstrate the new backend definition +API. diff --git a/lib/matplotlib/backends/backend_template.py b/lib/matplotlib/backends/backend_template.py index 67aea9d811f0..e4b3d79bd49b 100644 --- a/lib/matplotlib/backends/backend_template.py +++ b/lib/matplotlib/backends/backend_template.py @@ -136,23 +136,13 @@ class GraphicsContextTemplate(GraphicsContextBase): ######################################################################## -def show(*, block=None): - """ - For image backends - is not required. - For GUI backends - show() is usually the last line of a pyplot script and - tells the backend that it is time to draw. In interactive mode, this - should do nothing. - """ - for manager in Gcf.get_all_fig_managers(): - # do something to display the GUI - pass - - class FigureManagerTemplate(FigureManagerBase): """ Helper class for pyplot mode, wraps everything up into a neat bundle. - For non-interactive backends, the base class is sufficient. + For non-interactive backends, the base class is sufficient. For + interactive backends, see the documentation of the `.FigureManagerBase` + class for the list of methods that can/should be overridden. """ diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 34d46eeac918..58571c17b124 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -325,8 +325,14 @@ def draw_if_interactive(): # show is already present, as the latter may be here for backcompat. manager_class = getattr(getattr(backend_mod, "FigureCanvas", None), "manager_class", None) - if (manager_class.pyplot_show != FigureManagerBase.pyplot_show - or show is None): + # We can't compare directly manager_class.pyplot_show and FMB.pyplot_show + # because pyplot_show is a classmethod so the above constructs are bound + # classmethods, & thus always different (being bound to different classes). + manager_pyplot_show = vars(manager_class).get("pyplot_show") + base_pyplot_show = vars(FigureManagerBase).get("pyplot_show") + if (show is None + or (manager_pyplot_show is not None + and manager_pyplot_show != base_pyplot_show)): backend_mod.show = manager_class.pyplot_show _log.debug("Loaded backend %s version %s.", diff --git a/lib/matplotlib/tests/test_backend_template.py b/lib/matplotlib/tests/test_backend_template.py index 1bc666ce1814..d7e2a5cd1266 100644 --- a/lib/matplotlib/tests/test_backend_template.py +++ b/lib/matplotlib/tests/test_backend_template.py @@ -32,9 +32,19 @@ def test_load_old_api(monkeypatch): def test_show(monkeypatch): mpl_test_backend = SimpleNamespace(**vars(backend_template)) - mock_show = backend_template.FigureManagerTemplate.pyplot_show = \ - MagicMock() - del mpl_test_backend.show + mock_show = MagicMock() + monkeypatch.setattr( + mpl_test_backend.FigureManagerTemplate, "pyplot_show", mock_show) + monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend) + mpl.use("module://mpl_test_backend") + plt.show() + mock_show.assert_called_with() + + +def test_show_old_global_api(monkeypatch): + mpl_test_backend = SimpleNamespace(**vars(backend_template)) + mock_show = MagicMock() + monkeypatch.setattr(mpl_test_backend, "show", mock_show, raising=False) monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend) mpl.use("module://mpl_test_backend") plt.show()