Skip to content

Commit b719012

Browse files
authored
Merge pull request matplotlib#26491 from QuLogic/str-mosaic
TYP: Add common-type overloads of subplot_mosaic
2 parents ac376ea + 58d5aad commit b719012

File tree

5 files changed

+112
-27
lines changed

5 files changed

+112
-27
lines changed

doc/missing-references.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@
152152
"HashableList": [
153153
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.subplot_mosaic:1"
154154
],
155+
"HashableList[_HT]": [
156+
"doc/docstring of builtins.list:17"
157+
],
155158
"LineStyleType": [
156159
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.eventplot:1",
157160
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.hlines:1",
@@ -701,6 +704,9 @@
701704
"matplotlib.animation.TimedAnimation.to_jshtml": [
702705
"doc/api/_as_gen/matplotlib.animation.TimedAnimation.rst:28:<autosummary>:1"
703706
],
707+
"matplotlib.typing._HT": [
708+
"doc/docstring of builtins.list:17"
709+
],
704710
"mpl_toolkits.axislines.Axes": [
705711
"lib/mpl_toolkits/axisartist/axis_artist.py:docstring of mpl_toolkits.axisartist.axis_artist:7"
706712
],

lib/matplotlib/figure.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,15 +1749,11 @@ def _norm_per_subplot_kw(per_subplot_kw):
17491749
if isinstance(k, tuple):
17501750
for sub_key in k:
17511751
if sub_key in expanded:
1752-
raise ValueError(
1753-
f'The key {sub_key!r} appears multiple times.'
1754-
)
1752+
raise ValueError(f'The key {sub_key!r} appears multiple times.')
17551753
expanded[sub_key] = v
17561754
else:
17571755
if k in expanded:
1758-
raise ValueError(
1759-
f'The key {k!r} appears multiple times.'
1760-
)
1756+
raise ValueError(f'The key {k!r} appears multiple times.')
17611757
expanded[k] = v
17621758
return expanded
17631759

lib/matplotlib/figure.pyi

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
from collections.abc import Callable, Hashable, Iterable
12
import os
3+
from typing import Any, IO, Literal, TypeVar, overload
4+
5+
import numpy as np
6+
from numpy.typing import ArrayLike
27

38
from matplotlib.artist import Artist
49
from matplotlib.axes import Axes, SubplotBase
@@ -19,14 +24,10 @@ from matplotlib.lines import Line2D
1924
from matplotlib.patches import Rectangle, Patch
2025
from matplotlib.text import Text
2126
from matplotlib.transforms import Affine2D, Bbox, BboxBase, Transform
22-
23-
import numpy as np
24-
from numpy.typing import ArrayLike
25-
26-
from collections.abc import Callable, Iterable
27-
from typing import Any, IO, Literal, overload
2827
from .typing import ColorType, HashableList
2928

29+
_T = TypeVar("_T")
30+
3031
class FigureBase(Artist):
3132
artists: list[Artist]
3233
lines: list[Line2D]
@@ -200,21 +201,48 @@ class FigureBase(Artist):
200201
*,
201202
bbox_extra_artists: Iterable[Artist] | None = ...,
202203
) -> Bbox: ...
203-
204-
# Any in list of list is recursive list[list[Hashable | list[Hashable | ...]]] but that can't really be type checked
204+
@overload
205205
def subplot_mosaic(
206206
self,
207-
mosaic: str | HashableList,
207+
mosaic: str,
208+
*,
209+
sharex: bool = ...,
210+
sharey: bool = ...,
211+
width_ratios: ArrayLike | None = ...,
212+
height_ratios: ArrayLike | None = ...,
213+
empty_sentinel: str = ...,
214+
subplot_kw: dict[str, Any] | None = ...,
215+
per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | None = ...,
216+
gridspec_kw: dict[str, Any] | None = ...,
217+
) -> dict[str, Axes]: ...
218+
@overload
219+
def subplot_mosaic(
220+
self,
221+
mosaic: list[HashableList[_T]],
222+
*,
223+
sharex: bool = ...,
224+
sharey: bool = ...,
225+
width_ratios: ArrayLike | None = ...,
226+
height_ratios: ArrayLike | None = ...,
227+
empty_sentinel: _T = ...,
228+
subplot_kw: dict[str, Any] | None = ...,
229+
per_subplot_kw: dict[_T | tuple[_T, ...], dict[str, Any]] | None = ...,
230+
gridspec_kw: dict[str, Any] | None = ...,
231+
) -> dict[_T, Axes]: ...
232+
@overload
233+
def subplot_mosaic(
234+
self,
235+
mosaic: list[HashableList[Hashable]],
208236
*,
209237
sharex: bool = ...,
210238
sharey: bool = ...,
211239
width_ratios: ArrayLike | None = ...,
212240
height_ratios: ArrayLike | None = ...,
213241
empty_sentinel: Any = ...,
214242
subplot_kw: dict[str, Any] | None = ...,
215-
per_subplot_kw: dict[Any, dict[str, Any]] | None = ...,
216-
gridspec_kw: dict[str, Any] | None = ...
217-
) -> dict[Any, Axes]: ...
243+
per_subplot_kw: dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = ...,
244+
gridspec_kw: dict[str, Any] | None = ...,
245+
) -> dict[Hashable, Axes]: ...
218246

219247
class SubFigure(FigureBase):
220248
figure: Figure

lib/matplotlib/pyplot.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125

126126
_P = ParamSpec('_P')
127127
_R = TypeVar('_R')
128+
_T = TypeVar('_T')
128129

129130

130131
# We may not need the following imports here:
@@ -1602,8 +1603,56 @@ def subplots(
16021603
return fig, axs
16031604

16041605

1606+
@overload
1607+
def subplot_mosaic(
1608+
mosaic: str,
1609+
*,
1610+
sharex: bool = ...,
1611+
sharey: bool = ...,
1612+
width_ratios: ArrayLike | None = ...,
1613+
height_ratios: ArrayLike | None = ...,
1614+
empty_sentinel: str = ...,
1615+
subplot_kw: dict[str, Any] | None = ...,
1616+
gridspec_kw: dict[str, Any] | None = ...,
1617+
per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | None = ...,
1618+
**fig_kw: Any
1619+
) -> tuple[Figure, dict[str, matplotlib.axes.Axes]]: ...
1620+
1621+
1622+
@overload
1623+
def subplot_mosaic(
1624+
mosaic: list[HashableList[_T]],
1625+
*,
1626+
sharex: bool = ...,
1627+
sharey: bool = ...,
1628+
width_ratios: ArrayLike | None = ...,
1629+
height_ratios: ArrayLike | None = ...,
1630+
empty_sentinel: _T = ...,
1631+
subplot_kw: dict[str, Any] | None = ...,
1632+
gridspec_kw: dict[str, Any] | None = ...,
1633+
per_subplot_kw: dict[_T | tuple[_T, ...], dict[str, Any]] | None = ...,
1634+
**fig_kw: Any
1635+
) -> tuple[Figure, dict[_T, matplotlib.axes.Axes]]: ...
1636+
1637+
1638+
@overload
1639+
def subplot_mosaic(
1640+
mosaic: list[HashableList[Hashable]],
1641+
*,
1642+
sharex: bool = ...,
1643+
sharey: bool = ...,
1644+
width_ratios: ArrayLike | None = ...,
1645+
height_ratios: ArrayLike | None = ...,
1646+
empty_sentinel: Any = ...,
1647+
subplot_kw: dict[str, Any] | None = ...,
1648+
gridspec_kw: dict[str, Any] | None = ...,
1649+
per_subplot_kw: dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = ...,
1650+
**fig_kw: Any
1651+
) -> tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]: ...
1652+
1653+
16051654
def subplot_mosaic(
1606-
mosaic: str | HashableList,
1655+
mosaic: str | list[HashableList[_T]] | list[HashableList[Hashable]],
16071656
*,
16081657
sharex: bool = False,
16091658
sharey: bool = False,
@@ -1612,9 +1661,13 @@ def subplot_mosaic(
16121661
empty_sentinel: Any = '.',
16131662
subplot_kw: dict[str, Any] | None = None,
16141663
gridspec_kw: dict[str, Any] | None = None,
1615-
per_subplot_kw: dict[Hashable, dict[str, Any]] | None = None,
1616-
**fig_kw
1617-
) -> tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]:
1664+
per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] |
1665+
dict[_T | tuple[_T, ...], dict[str, Any]] |
1666+
dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = None,
1667+
**fig_kw: Any
1668+
) -> tuple[Figure, dict[str, matplotlib.axes.Axes]] | \
1669+
tuple[Figure, dict[_T, matplotlib.axes.Axes]] | \
1670+
tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]:
16181671
"""
16191672
Build a layout of Axes based on ASCII art or nested lists.
16201673
@@ -1716,12 +1769,13 @@ def subplot_mosaic(
17161769
17171770
"""
17181771
fig = figure(**fig_kw)
1719-
ax_dict = fig.subplot_mosaic(
1720-
mosaic, sharex=sharex, sharey=sharey,
1772+
ax_dict = fig.subplot_mosaic( # type: ignore[misc]
1773+
mosaic, # type: ignore[arg-type]
1774+
sharex=sharex, sharey=sharey,
17211775
height_ratios=height_ratios, width_ratios=width_ratios,
17221776
subplot_kw=subplot_kw, gridspec_kw=gridspec_kw,
17231777
empty_sentinel=empty_sentinel,
1724-
per_subplot_kw=per_subplot_kw,
1778+
per_subplot_kw=per_subplot_kw, # type: ignore[arg-type]
17251779
)
17261780
return fig, ax_dict
17271781

lib/matplotlib/typing.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"""
1212
from collections.abc import Hashable, Sequence
1313
import pathlib
14-
from typing import Any, Literal, Union
14+
from typing import Any, Literal, TypeVar, Union
1515

1616
from . import path
1717
from ._enums import JoinStyle, CapStyle
@@ -55,5 +55,6 @@
5555
Sequence[Union[str, pathlib.Path, dict[str, Any]]],
5656
]
5757

58-
HashableList = list[Union[Hashable, "HashableList"]]
58+
_HT = TypeVar("_HT", bound=Hashable)
59+
HashableList = list[Union[_HT, "HashableList[_HT]"]]
5960
"""A nested list of Hashable values."""

0 commit comments

Comments
 (0)