From cc62eba10d39e5a7659c98337801ab8aee013977 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 23 Jan 2026 04:54:12 -0500 Subject: [PATCH 1/3] Remove mutable defaults from tool manager functions This is generally frowned upon (though we don't actually change it, so it's safe), but more importantly, Sphinx tries to put all the values into the docstring, which just looks bad. --- lib/matplotlib/backend_tools.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/backend_tools.py b/lib/matplotlib/backend_tools.py index 0c03bd0800f4..82007e8b6921 100644 --- a/lib/matplotlib/backend_tools.py +++ b/lib/matplotlib/backend_tools.py @@ -934,6 +934,7 @@ def trigger(self, *args, **kwargs): self.toolmanager.message_event(message, self) +#: The default tools to add to a tool manager. default_tools = {'home': ToolHome, 'back': ToolBack, 'forward': ToolForward, 'zoom': ToolZoom, 'pan': ToolPan, 'subplots': ConfigureSubplotsBase, @@ -953,12 +954,13 @@ def trigger(self, *args, **kwargs): 'copy': ToolCopyToClipboardBase, } +#: The default tools to add to a container. default_toolbar_tools = [['navigation', ['home', 'back', 'forward']], ['zoompan', ['pan', 'zoom', 'subplots']], ['io', ['save', 'help']]] -def add_tools_to_manager(toolmanager, tools=default_tools): +def add_tools_to_manager(toolmanager, tools=None): """ Add multiple tools to a `.ToolManager`. @@ -968,14 +970,16 @@ def add_tools_to_manager(toolmanager, tools=default_tools): Manager to which the tools are added. tools : {str: class_like}, optional The tools to add in a {name: tool} dict, see - `.backend_managers.ToolManager.add_tool` for more info. + `.backend_managers.ToolManager.add_tool` for more info. If not specified, then + defaults to `.default_tools`. """ - + if tools is None: + tools = default_tools for name, tool in tools.items(): toolmanager.add_tool(name, tool) -def add_tools_to_container(container, tools=default_toolbar_tools): +def add_tools_to_container(container, tools=None): """ Add multiple tools to the container. @@ -987,9 +991,11 @@ def add_tools_to_container(container, tools=default_toolbar_tools): tools : list, optional List in the form ``[[group1, [tool1, tool2 ...]], [group2, [...]]]`` where the tools ``[tool1, tool2, ...]`` will display in group1. - See `.backend_bases.ToolContainerBase.add_tool` for details. + See `.backend_bases.ToolContainerBase.add_tool` for details. If not specified, + then defaults to `.default_toolbar_tools`. """ - + if tools is None: + tools = default_toolbar_tools for group, grouptools in tools: for position, tool in enumerate(grouptools): container.add_tool(tool, group, position) From 6663149aaaff91bf037d033e38ee30d0ae5be7b2 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 23 Jan 2026 05:52:16 -0500 Subject: [PATCH 2/3] DOC: Use the old class-based autodoc with Sphinx 9 The new version appears to be causing some issues for our missing reference checks, so reverting back to the old implementation should buy us some time to fix things. --- doc/conf.py | 1 + lib/matplotlib/backend_tools.pyi | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 806561f0bfc0..d06a88b35904 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -899,3 +899,4 @@ def setup(app): if sphinx.version_info[:2] < (7, 1): app.connect('html-page-context', add_html_cache_busting, priority=1000) generate_ScalarMappable_docs() + app.config.autodoc_use_legacy_class_based = True diff --git a/lib/matplotlib/backend_tools.pyi b/lib/matplotlib/backend_tools.pyi index 32fe8c2f5a79..fa89e3d66871 100644 --- a/lib/matplotlib/backend_tools.pyi +++ b/lib/matplotlib/backend_tools.pyi @@ -112,10 +112,10 @@ class ToolHelpBase(ToolBase): class ToolCopyToClipboardBase(ToolBase): ... -default_tools: dict[str, ToolBase] +default_tools: dict[str, type[ToolBase]] default_toolbar_tools: list[list[str | list[str]]] def add_tools_to_manager( - toolmanager: ToolManager, tools: dict[str, type[ToolBase]] = ... + toolmanager: ToolManager, tools: dict[str, type[ToolBase]] | None = ... ) -> None: ... -def add_tools_to_container(container: ToolContainerBase, tools: list[Any] = ...) -> None: ... +def add_tools_to_container(container: ToolContainerBase, tools: list[Any] | None = ...) -> None: ... From cde8c89deb0b4c945af17d280ff381a561a35d25 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 23 Jan 2026 19:36:52 -0500 Subject: [PATCH 3/3] DOC: Fix cross-references to new _Buttons class --- lib/matplotlib/widgets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index 84fc3a947f8e..97c2cb46e33a 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -1152,7 +1152,7 @@ class CheckButtons(_Buttons): For the check buttons to remain responsive you must keep a reference to this object. - Connect to the CheckButtons with the `.on_clicked` method. + Connect to the CheckButtons with the `~._Buttons.on_clicked` method. Attributes ---------- @@ -1652,7 +1652,7 @@ class RadioButtons(_Buttons): For the buttons to remain responsive you must keep a reference to this object. - Connect to the RadioButtons with the `.on_clicked` method. + Connect to the RadioButtons with the `~._Buttons.on_clicked` method. Attributes ----------