From ed03cea2dde9b9944a1c4ccfde50a5ed137c483b Mon Sep 17 00:00:00 2001 From: karlhillx Date: Sat, 4 Jul 2026 17:45:17 -0400 Subject: [PATCH 1/5] Widen return type of pyplot.subplot_tool / NavigationToolbar2.configure_subplots to Any Per timhoffm on #31979. The Qt backends return QDialog subclasses and the toolmanager branch already returns None, so the prior annotation was misleading. Update docstring to describe the backend-dependent return value. Also drop the now-unused TYPE_CHECKING import of SubplotTool and alphabetize the typing import. Closes #31979 --- lib/matplotlib/backend_bases.pyi | 2 +- lib/matplotlib/pyplot.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/backend_bases.pyi b/lib/matplotlib/backend_bases.pyi index fe492f0dde66..155bb6a854c3 100644 --- a/lib/matplotlib/backend_bases.pyi +++ b/lib/matplotlib/backend_bases.pyi @@ -484,7 +484,7 @@ class NavigationToolbar2: def release_zoom(self, event: Event) -> None: ... def push_current(self) -> None: ... subplot_tool: widgets.SubplotTool - def configure_subplots(self, *args: Any) -> widgets.SubplotTool: ... + def configure_subplots(self, *args: Any) -> Any: ... def save_figure(self, *args) -> str | None | object: ... def update(self) -> None: ... def set_history_buttons(self) -> None: ... diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 8cdacca8c0a3..566815d9c8e6 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -54,7 +54,7 @@ import sys import threading import time -from typing import IO, TYPE_CHECKING, cast, overload +from typing import Any, IO, TYPE_CHECKING, cast, overload from cycler import cycler # noqa: F401 import matplotlib @@ -153,7 +153,6 @@ ResizeEventType, LogLevel ) - from matplotlib.widgets import SubplotTool from matplotlib._api import _Unset @@ -2152,13 +2151,15 @@ def twiny(ax: matplotlib.axes.Axes | None = None) -> _AxesBase: return ax1 -def subplot_tool(targetfig: Figure | None = None) -> SubplotTool | None: +def subplot_tool(targetfig: Figure | None = None) -> Any: """ Launch a subplot tool window for a figure. Returns ------- - `matplotlib.widgets.SubplotTool` + The subplot tool window. May be a `~matplotlib.widgets.SubplotTool` + (widgets backend), a backend-native dialog (e.g. Qt), or `None` for + backends that use the toolmanager. """ if targetfig is None: targetfig = gcf() From 709e9f28b7476fce26cc0ef10fbb4e1445aa83d1 Mon Sep 17 00:00:00 2001 From: karlhillx Date: Sat, 4 Jul 2026 17:48:08 -0400 Subject: [PATCH 2/5] Fix ruff F811: remove Any from inner TYPE_CHECKING block --- lib/matplotlib/pyplot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 566815d9c8e6..79342fac02b6 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -92,7 +92,7 @@ from collections.abc import Callable, Hashable, Iterable, Sequence import pathlib import os - from typing import Any, BinaryIO, Literal + from typing import BinaryIO, Literal import PIL.Image from numpy.typing import ArrayLike From f4fe5a758c1e3eff7b7d3ca38ab3aeb65b0cafa8 Mon Sep 17 00:00:00 2001 From: Karl Hill Date: Sat, 4 Jul 2026 17:51:17 -0400 Subject: [PATCH 3/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- lib/matplotlib/pyplot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 79342fac02b6..dd4c2acc8e45 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2151,7 +2151,7 @@ def twiny(ax: matplotlib.axes.Axes | None = None) -> _AxesBase: return ax1 -def subplot_tool(targetfig: Figure | None = None) -> Any: +def subplot_tool(targetfig: Figure | None = None) -> object | None: """ Launch a subplot tool window for a figure. From d2b90f07aca1606f91c696d17965d8e9ad8079f5 Mon Sep 17 00:00:00 2001 From: karlhillx Date: Sat, 4 Jul 2026 18:17:16 -0400 Subject: [PATCH 4/5] Format subplot_tool Returns section per numpydoc --- lib/matplotlib/pyplot.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index dd4c2acc8e45..c271342e4513 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2157,9 +2157,10 @@ def subplot_tool(targetfig: Figure | None = None) -> object | None: Returns ------- - The subplot tool window. May be a `~matplotlib.widgets.SubplotTool` - (widgets backend), a backend-native dialog (e.g. Qt), or `None` for - backends that use the toolmanager. + `~matplotlib.widgets.SubplotTool` or None + The subplot tool window. Returns a `~matplotlib.widgets.SubplotTool` + for the widgets backend, a backend-native dialog (e.g. Qt) for other + backends, or `None` for backends using the toolmanager. """ if targetfig is None: targetfig = gcf() From e1e96ecb8cd2e2f33b6d920c9f21d324ff1cf9c1 Mon Sep 17 00:00:00 2001 From: karlhillx Date: Sun, 5 Jul 2026 21:17:37 -0400 Subject: [PATCH 5/5] Use object return type for subplot_tool; generalize docstring Address review feedback: keep the public return annotation as object | None (safer than Any, which disables type checking for callers) and match the configure_subplots stub to object. Rewrite the Returns description to cover backends without a native dialog (e.g. macosx) as an implementation-specific value. Drop the unnecessary top-level Any import move. --- lib/matplotlib/backend_bases.pyi | 2 +- lib/matplotlib/pyplot.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/backend_bases.pyi b/lib/matplotlib/backend_bases.pyi index 155bb6a854c3..787c2ea81d6f 100644 --- a/lib/matplotlib/backend_bases.pyi +++ b/lib/matplotlib/backend_bases.pyi @@ -484,7 +484,7 @@ class NavigationToolbar2: def release_zoom(self, event: Event) -> None: ... def push_current(self) -> None: ... subplot_tool: widgets.SubplotTool - def configure_subplots(self, *args: Any) -> Any: ... + def configure_subplots(self, *args: Any) -> object: ... def save_figure(self, *args) -> str | None | object: ... def update(self) -> None: ... def set_history_buttons(self) -> None: ... diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index c271342e4513..39ff36acd86d 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -54,7 +54,7 @@ import sys import threading import time -from typing import Any, IO, TYPE_CHECKING, cast, overload +from typing import IO, TYPE_CHECKING, cast, overload from cycler import cycler # noqa: F401 import matplotlib @@ -92,7 +92,7 @@ from collections.abc import Callable, Hashable, Iterable, Sequence import pathlib import os - from typing import BinaryIO, Literal + from typing import Any, BinaryIO, Literal import PIL.Image from numpy.typing import ArrayLike @@ -2157,10 +2157,10 @@ def subplot_tool(targetfig: Figure | None = None) -> object | None: Returns ------- - `~matplotlib.widgets.SubplotTool` or None - The subplot tool window. Returns a `~matplotlib.widgets.SubplotTool` - for the widgets backend, a backend-native dialog (e.g. Qt) for other - backends, or `None` for backends using the toolmanager. + object or None + The subplot tool window: a `~matplotlib.widgets.SubplotTool` for the + widgets backend, an implementation-specific value for other backends + (e.g. a Qt dialog), or `None` for backends using the toolmanager. """ if targetfig is None: targetfig = gcf()