Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 58d5aad

Browse files
committed
TYP: Add common type overloads of subplot_mosaic
I'll assert, without proof, that passing a single string, a mosaic list of strings, or a mosaic list all of the same type is more common than passing arbitrary unrelated hashables. Thus it is somewhat convenient if the return type stipulates that the resulting dictionary is also keyed with strings or the common type. This also fixes the type of the `per_subplot_kw` argument, which also allows dictionary keys of tuples of the entries.
1 parent 75ef6e2 commit 58d5aad

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)