From 8cfff73704b50aa4361417afd2186b368dd7661e Mon Sep 17 00:00:00 2001 From: Zhang Maiyun Date: Sat, 6 Jun 2026 16:11:22 -0400 Subject: [PATCH 1/3] Add pyi and some type hints for backend_pdf --- lib/matplotlib/backends/backend_pdf.pyi | 266 ++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 lib/matplotlib/backends/backend_pdf.pyi diff --git a/lib/matplotlib/backends/backend_pdf.pyi b/lib/matplotlib/backends/backend_pdf.pyi new file mode 100644 index 000000000000..813046b708eb --- /dev/null +++ b/lib/matplotlib/backends/backend_pdf.pyi @@ -0,0 +1,266 @@ +import os +import types +from datetime import datetime +from enum import Enum +from functools import total_ordering +from typing import IO, Any, Protocol, Self, TypeAlias + +import numpy as np +from _typeshed import ReadableBuffer, SupportsWrite + +from matplotlib import _api +from matplotlib.backend_bases import FigureCanvasBase, GraphicsContextBase +from matplotlib.dviread import DviFont +from matplotlib.figure import Figure +from matplotlib.font_manager import FontPath +from matplotlib.transforms import BboxBase + +from . import _backend_pdf_ps + +class _SupportsPdfRepr(Protocol): + def pdfRepr(self) -> bytes: ... + +_SupportsPdfReprExt: TypeAlias = ( + _SupportsPdfRepr + | float + | np.floating + | bool + | int + | np.integer + | str + | bytes + | dict[Name | bytes, _SupportsPdfReprExt] + | list[_SupportsPdfReprExt] + | tuple[_SupportsPdfReprExt, ...] + | None + | datetime + | BboxBase +) + +_MetadataDict: TypeAlias = dict[str, str | datetime | Name] + +def pdfRepr(obj: _SupportsPdfReprExt) -> bytes: ... + +class Reference: + def __init__(self, id: int) -> None: ... + def __repr__(self) -> str: ... + def pdfRepr(self) -> bytes: ... + def write( + self, contents: _SupportsPdfReprExt, file: SupportsWrite[bytes] + ) -> None: ... + +@total_ordering +class Name: + def __init__(self, name: Self | bytes) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + def __eq__(self, other: Any) -> bool: ... + def __lt__(self, other: Any) -> bool: ... + def __hash__(self) -> int: ... + def pdfRepr(self) -> bytes: ... + +class Verbatim: + def __init__(self, x: bytes) -> None: ... + def pdfRepr(self) -> bytes: ... + +class Op(Enum): + close_fill_stroke = b"b" + fill_stroke = b"B" + fill = b"f" + closepath = b"h" + close_stroke = b"s" + stroke = b"S" + endpath = b"n" + begin_text = b"BT" + end_text = b"ET" + curveto = b"c" + rectangle = b"re" + lineto = b"l" + moveto = b"m" + concat_matrix = b"cm" + use_xobject = b"Do" + setgray_stroke = b"G" + setgray_nonstroke = b"g" + setrgb_stroke = b"RG" + setrgb_nonstroke = b"rg" + setcolorspace_stroke = b"CS" + setcolorspace_nonstroke = b"cs" + setcolor_stroke = b"SCN" + setcolor_nonstroke = b"scn" + setdash = b"d" + setlinejoin = b"j" + setlinecap = b"J" + setgstate = b"gs" + gsave = b"q" + grestore = b"Q" + textpos = b"Td" + selectfont = b"Tf" + textmatrix = b"Tm" + textrise = b"Ts" + show = b"Tj" + showkern = b"TJ" + setlinewidth = b"w" + clip = b"W" + shading = b"sh" + def pdfRepr(self) -> bytes: ... + @classmethod + def paint_path(cls, fill: bool, stroke: bool) -> bytes: ... + +class Stream: + def __init__( + self, + id: int, + len: Reference | None, + file: PdfFile, + extra: dict[Name, Any] | None = None, + png: dict[Any, Any] | None = None, + ) -> None: ... + def end(self) -> None: ... + def write(self, data: bytes) -> None: ... + +class PdfFile: + def __init__( + self, + filename: str | os.PathLike | IO[Any], + metadata: _MetadataDict | None = None, + ) -> None: ... + @property + def dviFontInfo(self) -> dict[Name, types.SimpleNamespace]: ... + def newPage(self, width: float, height: float) -> None: ... + def newTextnote( + self, + text: _SupportsPdfReprExt, + positionRect: list[int | float] = [-100, -100, 0, 0], + ) -> None: ... + def finalize(self) -> None: ... + def write(self, data: ReadableBuffer) -> None: ... + def output(self, *data: _SupportsPdfReprExt) -> None: ... + def beginStream( + self, + id: int, + len: Reference | None, + extra: dict[Name, Any] | None = None, + png: dict[Any, Any] | None = None, + ) -> None: ... + def endStream(self) -> None: ... + def outputStream( + self, ref: Reference, data: bytes, *, extra: dict[Name, Any] | None = None + ) -> None: ... + def fontName(self, fontprop: FontPath | str, subset: int = 0) -> Name | None: ... + def dviFontName(self, dvifont: DviFont) -> Name: ... + def writeFonts(self) -> None: ... + @_api.delete_parameter("3.11", "fontfile") + def createType1Descriptor(self, t1font, fontfile=None): ... + def embedTTF(self, filename, subset_index, charmap): ... + def alphaState(self, alpha): ... + def writeExtGSTates(self): ... + def hatchPattern(self, hatch_style): ... + def writeHatches(self): ... + def addGouraudTriangles(self, points, colors): ... + def writeGouraudTriangles(self): ... + def imageObject(self, image): ... + def writeImages(self): ... + def markerObject(self, path, trans, fill, stroke, lw, joinstyle, capstyle): ... + def writeMarkers(self): ... + def pathCollectionObject(self, gc, path, trans, padding, filled, stroked): ... + def writePathCollectionTemplates(self): ... + @staticmethod + def pathOperations(path, transform, clip=None, simplify=None, sketch=None): ... + def writePath(self, path, transform, clip=False, sketch=None): ... + def reserveObject(self, name=""): ... + def recordXref(self, id): ... + def writeObject(self, object, contents): ... + def writeXref(self): ... + def writeInfoDict(self): ... + def writeTrailer(self): ... + +class RendererPdf(_backend_pdf_ps.RendererPDFPSBase): + def __init__(self, file, image_dpi, height, width): ... + def finalize(self) -> None: ... + def check_gc(self, gc, fillcolor=None): ... + def get_image_magnification(self): ... + def draw_image(self, gc, x, y, im, transform=None): ... + def draw_path(self, gc, path, transform, rgbFace=None): ... + def draw_path_collection( + self, + gc, + master_transform, + paths, + all_transforms, + offsets, + offset_trans, + facecolors, + edgecolors, + linewidths, + linestyles, + antialiaseds, + urls, + offset_position, + *, + hatchcolors=None, + ): ... + def draw_markers( + self, gc, marker_path, marker_trans, path, trans, rgbFace=None + ): ... + def draw_gouraud_triangles(self, gc, points, colors, trans): ... + def draw_mathtext(self, gc, x, y, s, prop, angle): ... + def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None): ... + def encode_string(self, s, fonttype): ... + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): ... + def new_gc(self) -> GraphicsContextPdf: ... + +class GraphicsContextPdf(GraphicsContextBase): + def __init__(self, file): ... + def __repr__(self): ... + def stroke(self): ... + def fill(self, *args): ... + def paint(self): ... + def capstyle_cmd(self, style): ... + def joinstyle_cmd(self, style): ... + def linewidth_cmd(self, width): ... + def dash_cmd(self, dashes): ... + def alpha_cmd(self, alpha, forced, effective_alphas): ... + def hatch_cmd(self, hatch, hatch_color, hatch_linewidth): ... + def rgb_cmd(self, rgb): ... + def fillcolor_cmd(self, rgb): ... + def push(self): ... + def pop(self): ... + def clip_cmd(self, cliprect, clippath): ... + def delta(self, other): ... + def copy_properties(self, other): ... + def finalize(self) -> None: ... + +class PdfPages: + def __init__( + self, + filename: str | os.PathLike | IO[Any], + keep_empty: None = None, + metadata: _MetadataDict | None = None, + ) -> None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: object, exc_tb: object + ) -> None: ... + def close(self) -> None: ... + def infodict(self) -> _MetadataDict: ... + def savefig( + self, figure: Figure | int | None = None, **kwargs: dict[str, Any] + ) -> None: ... + def get_pagecount(self) -> int: ... + def attach_note( + self, + text: _SupportsPdfReprExt, + positionRect: list[int | float] = [-100, -100, 0, 0], + ) -> None: ... + +class FigureCanvasPdf(FigureCanvasBase): + filetypes: dict[str, str] + def get_default_filetype(cls) -> str: ... + def print_pdf( + self, + filename: PdfPages | IO[Any], + *, + bbox_inches_restore: list[int | float] | None = None, + metadata: _MetadataDict | None = None, + ) -> None: ... + def draw(self) -> None: ... From 61e2974da9953d015764c7d01b31284748fd6e2d Mon Sep 17 00:00:00 2001 From: Zhang Maiyun Date: Sat, 6 Jun 2026 17:32:51 -0400 Subject: [PATCH 2/3] Type all return types --- lib/matplotlib/backends/backend_pdf.pyi | 127 +++++++++++++++--------- 1 file changed, 79 insertions(+), 48 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.pyi b/lib/matplotlib/backends/backend_pdf.pyi index 813046b708eb..2379aaecd724 100644 --- a/lib/matplotlib/backends/backend_pdf.pyi +++ b/lib/matplotlib/backends/backend_pdf.pyi @@ -1,5 +1,7 @@ import os +import pathlib import types +from collections.abc import Iterable, Callable from datetime import datetime from enum import Enum from functools import total_ordering @@ -7,8 +9,10 @@ from typing import IO, Any, Protocol, Self, TypeAlias import numpy as np from _typeshed import ReadableBuffer, SupportsWrite +from numpy import typing as npt from matplotlib import _api +from matplotlib._type1font import Type1Font from matplotlib.backend_bases import FigureCanvasBase, GraphicsContextBase from matplotlib.dviread import DviFont from matplotlib.figure import Figure @@ -150,37 +154,51 @@ class PdfFile: def dviFontName(self, dvifont: DviFont) -> Name: ... def writeFonts(self) -> None: ... @_api.delete_parameter("3.11", "fontfile") - def createType1Descriptor(self, t1font, fontfile=None): ... - def embedTTF(self, filename, subset_index, charmap): ... - def alphaState(self, alpha): ... - def writeExtGSTates(self): ... + def createType1Descriptor( + self, t1font: Type1Font, fontfile: Any = None + ) -> Reference: ... + def embedTTF( + self, + filename: Iterable[str | pathlib.Path | bytes] | str | pathlib.Path | bytes, + subset_index: int, + charmap: dict[int, int], + ) -> Reference: ... + # TODO: It seems that `alpha` is a dead value from my naive search + def alphaState(self, alpha: int) -> Name: ... + def writeExtGSTates(self) -> None: ... def hatchPattern(self, hatch_style): ... - def writeHatches(self): ... + def writeHatches(self) -> None: ... def addGouraudTriangles(self, points, colors): ... - def writeGouraudTriangles(self): ... - def imageObject(self, image): ... - def writeImages(self): ... - def markerObject(self, path, trans, fill, stroke, lw, joinstyle, capstyle): ... - def writeMarkers(self): ... - def pathCollectionObject(self, gc, path, trans, padding, filled, stroked): ... - def writePathCollectionTemplates(self): ... + def writeGouraudTriangles(self) -> None: ... + def imageObject(self, image: npt.NDArray[np.uint8]) -> Name: ... + def writeImages(self) -> None: ... + def markerObject( + self, path, trans, fill, stroke, lw, joinstyle, capstyle + ) -> Name: ... + def writeMarkers(self) -> None: ... + def pathCollectionObject( + self, gc, path, trans, padding, filled, stroked + ) -> Name: ... + def writePathCollectionTemplates(self) -> None: ... @staticmethod - def pathOperations(path, transform, clip=None, simplify=None, sketch=None): ... - def writePath(self, path, transform, clip=False, sketch=None): ... - def reserveObject(self, name=""): ... - def recordXref(self, id): ... - def writeObject(self, object, contents): ... - def writeXref(self): ... - def writeInfoDict(self): ... - def writeTrailer(self): ... + def pathOperations( + path, transform, clip=None, simplify=None, sketch=None + ) -> list[Verbatim]: ... + def writePath(self, path, transform, clip=False, sketch=None) -> None: ... + def reserveObject(self, name: str = "") -> Reference: ... + def recordXref(self, id: int) -> None: ... + def writeObject(self, object, contents) -> None: ... + def writeXref(self) -> None: ... + def writeInfoDict(self) -> None: ... + def writeTrailer(self) -> None: ... class RendererPdf(_backend_pdf_ps.RendererPDFPSBase): def __init__(self, file, image_dpi, height, width): ... def finalize(self) -> None: ... - def check_gc(self, gc, fillcolor=None): ... - def get_image_magnification(self): ... - def draw_image(self, gc, x, y, im, transform=None): ... - def draw_path(self, gc, path, transform, rgbFace=None): ... + def check_gc(self, gc, fillcolor=None) -> None: ... + def get_image_magnification(self) -> float: ... + def draw_image(self, gc, x, y, im, transform=None) -> None: ... + def draw_path(self, gc, path, transform, rgbFace=None) -> None: ... def draw_path_collection( self, gc, @@ -198,37 +216,50 @@ class RendererPdf(_backend_pdf_ps.RendererPDFPSBase): offset_position, *, hatchcolors=None, - ): ... + ) -> None: ... def draw_markers( self, gc, marker_path, marker_trans, path, trans, rgbFace=None - ): ... - def draw_gouraud_triangles(self, gc, points, colors, trans): ... - def draw_mathtext(self, gc, x, y, s, prop, angle): ... - def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None): ... - def encode_string(self, s, fonttype): ... - def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): ... + ) -> None: ... + def draw_gouraud_triangles(self, gc, points, colors, trans) -> None: ... + def draw_mathtext(self, gc, x, y, s, prop, angle) -> None: ... + def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None) -> None: ... + def encode_string(self, s: str, fonttype: int) -> bytes: ... + def draw_text( + self, gc, x, y, s: str, prop, angle, ismath=False, mtext=None + ) -> None: ... def new_gc(self) -> GraphicsContextPdf: ... +_Command: TypeAlias = list[_SupportsPdfReprExt] +_CommandFunction: TypeAlias = Callable[[GraphicsContextBase, Any, ...], _Command] + class GraphicsContextPdf(GraphicsContextBase): + file: PdfFile + capstyles: dict[str, int] + joinstyles: dict[str, int] + commands: tuple[tuple[str, ...], _CommandFunction] def __init__(self, file): ... def __repr__(self): ... - def stroke(self): ... - def fill(self, *args): ... - def paint(self): ... - def capstyle_cmd(self, style): ... - def joinstyle_cmd(self, style): ... - def linewidth_cmd(self, width): ... - def dash_cmd(self, dashes): ... - def alpha_cmd(self, alpha, forced, effective_alphas): ... - def hatch_cmd(self, hatch, hatch_color, hatch_linewidth): ... - def rgb_cmd(self, rgb): ... - def fillcolor_cmd(self, rgb): ... - def push(self): ... - def pop(self): ... - def clip_cmd(self, cliprect, clippath): ... - def delta(self, other): ... - def copy_properties(self, other): ... - def finalize(self) -> None: ... + def stroke(self) -> bool: ... + def fill(self, *args) -> bool: ... + def paint(self) -> Op: ... + def capstyle_cmd(self, style: int) -> _Command: ... + def joinstyle_cmd(self, style) -> _Command: ... + def linewidth_cmd(self, width) -> _Command: ... + def dash_cmd( + self, dashes: tuple[float, Iterable[_SupportsPdfReprExt]] + ) -> _Command: ... + # TODO: unable to determine types for unused `alpha`, `forced` + def alpha_cmd(self, alpha: int, forced: bool, effective_alphas) -> _Command: ... + def hatch_cmd(self, hatch, hatch_color, hatch_linewidth) -> _Command: ... + # TODO: determine type of `rgb[:]` + def rgb_cmd(self, rgb: list[int]) -> _Command: ... + def fillcolor_cmd(self, rgb: list[int]) -> _Command: ... + def push(self) -> list[Op]: ... + def pop(self) -> list[Op]: ... + def clip_cmd(self, cliprect, clippath) -> _Command: ... + def delta(self, other: GraphicsContextBase) -> _Command: ... + def copy_properties(self, other: GraphicsContextBase) -> None: ... + def finalize(self) -> list[Op]: ... class PdfPages: def __init__( From b67f1861346ceefbb9a38c894b4aafe94750efb8 Mon Sep 17 00:00:00 2001 From: Zhang Maiyun Date: Sat, 6 Jun 2026 18:34:33 -0400 Subject: [PATCH 3/3] Finish all type hints --- lib/matplotlib/backends/backend_pdf.pyi | 238 ++++++++++++++++++------ 1 file changed, 178 insertions(+), 60 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.pyi b/lib/matplotlib/backends/backend_pdf.pyi index 2379aaecd724..d3cab7130589 100644 --- a/lib/matplotlib/backends/backend_pdf.pyi +++ b/lib/matplotlib/backends/backend_pdf.pyi @@ -1,26 +1,45 @@ import os import pathlib import types -from collections.abc import Iterable, Callable +from collections.abc import Callable, Iterable, Sequence from datetime import datetime from enum import Enum from functools import total_ordering -from typing import IO, Any, Protocol, Self, TypeAlias +from typing import IO, Any, Literal, Protocol, Self, TypeAlias import numpy as np from _typeshed import ReadableBuffer, SupportsWrite from numpy import typing as npt -from matplotlib import _api +from matplotlib import _api, path, transforms from matplotlib._type1font import Type1Font from matplotlib.backend_bases import FigureCanvasBase, GraphicsContextBase from matplotlib.dviread import DviFont from matplotlib.figure import Figure -from matplotlib.font_manager import FontPath -from matplotlib.transforms import BboxBase +from matplotlib.font_manager import FontPath, FontProperties +from matplotlib.text import Text +from matplotlib.transforms import BboxBase, Transform, TransformedBbox, TransformedPath +from matplotlib.typing import ( + CapStyleType, + ColorType, + JoinStyleType, + LineStyleType, + RGBColorType, +) from . import _backend_pdf_ps +# XXX: Some of these might be worth moving to `mpl.typing` +_CommandType: TypeAlias = list[_SupportsPdfReprExt] +_CommandFuncType: TypeAlias = Callable[..., _CommandType] +_RectangleType: TypeAlias = tuple[float, float, float, float] | list[float] +# struct definition SketchParams in _backend_agg_basic_types.h +_SketchParamsType: TypeAlias = tuple[float, float, float] +_HatchType: TypeAlias = str +_HatchStyleType: TypeAlias = tuple[ + ColorType | None, ColorType | None, _HatchType | None, float +] + class _SupportsPdfRepr(Protocol): def pdfRepr(self) -> bytes: ... @@ -163,101 +182,199 @@ class PdfFile: subset_index: int, charmap: dict[int, int], ) -> Reference: ... - # TODO: It seems that `alpha` is a dead value from my naive search def alphaState(self, alpha: int) -> Name: ... def writeExtGSTates(self) -> None: ... - def hatchPattern(self, hatch_style): ... + def hatchPattern(self, hatch_style: _HatchStyleType) -> Name: ... def writeHatches(self) -> None: ... - def addGouraudTriangles(self, points, colors): ... + def addGouraudTriangles( + self, points: npt.ArrayLike, colors: npt.ArrayLike + ) -> tuple[Name, Reference]: ... def writeGouraudTriangles(self) -> None: ... def imageObject(self, image: npt.NDArray[np.uint8]) -> Name: ... def writeImages(self) -> None: ... def markerObject( - self, path, trans, fill, stroke, lw, joinstyle, capstyle + self, + path: path.Path, + trans: Transform, + fill: bool, + stroke: bool, + lw: float, + joinstyle: JoinStyleType, + capstyle: CapStyleType, ) -> Name: ... def writeMarkers(self) -> None: ... def pathCollectionObject( - self, gc, path, trans, padding, filled, stroked + self, + gc: GraphicsContextBase, + path: path.Path, + trans: Transform, + padding: float, + filled: bool, + stroked: bool, ) -> Name: ... def writePathCollectionTemplates(self) -> None: ... + # types in _path.h::convert_to_string @staticmethod def pathOperations( - path, transform, clip=None, simplify=None, sketch=None + path: path.Path, + transform: Transform, + clip: _RectangleType | None = None, + simplify: bool | None = None, + sketch: _SketchParamsType | None = None, ) -> list[Verbatim]: ... - def writePath(self, path, transform, clip=False, sketch=None) -> None: ... + def writePath( + self, + path: path.Path, + transform: Transform, + clip: bool = False, + sketch: _SketchParamsType | None = None, + ) -> None: ... def reserveObject(self, name: str = "") -> Reference: ... def recordXref(self, id: int) -> None: ... - def writeObject(self, object, contents) -> None: ... + def writeObject( + self, object: _SupportsPdfReprExt, contents: dict[str, _SupportsPdfReprExt] + ) -> None: ... def writeXref(self) -> None: ... def writeInfoDict(self) -> None: ... def writeTrailer(self) -> None: ... class RendererPdf(_backend_pdf_ps.RendererPDFPSBase): - def __init__(self, file, image_dpi, height, width): ... + paths: tuple[ + Name, + path.Path, + Transform, + Reference, + JoinStyleType, + CapStyleType, + float, + bool, + bool, + ] + def __init__( + self, file: PdfFile, image_dpi: float, height: float, width: float + ): ... def finalize(self) -> None: ... - def check_gc(self, gc, fillcolor=None) -> None: ... + def check_gc( + self, gc: GraphicsContextBase, fillcolor: ColorType | None = None + ) -> None: ... def get_image_magnification(self) -> float: ... - def draw_image(self, gc, x, y, im, transform=None) -> None: ... - def draw_path(self, gc, path, transform, rgbFace=None) -> None: ... + def draw_image( + self, + gc: GraphicsContextBase, + x: float, + y: float, + im: npt.ArrayLike, + transform: transforms.Affine2DBase | None = None, + ) -> None: ... + def draw_path( + self, + gc: GraphicsContextBase, + path: path.Path, + transform: Transform, + rgbFace: ColorType | None = None, + ) -> None: ... def draw_path_collection( self, - gc, - master_transform, - paths, - all_transforms, - offsets, - offset_trans, - facecolors, - edgecolors, - linewidths, - linestyles, - antialiaseds, - urls, - offset_position, + gc: GraphicsContextBase, + master_transform: Transform, + paths: Sequence[path.Path], + all_transforms: Sequence[npt.ArrayLike], + offsets: npt.ArrayLike | Sequence[npt.ArrayLike], + offset_trans: Transform, + facecolors: ColorType | Sequence[ColorType], + edgecolors: ColorType | Sequence[ColorType], + linewidths: float | Sequence[float], + linestyles: LineStyleType | Sequence[LineStyleType], + antialiaseds: bool | Sequence[bool], + urls: str | Sequence[str], + offset_position: Any, *, - hatchcolors=None, + hatchcolors: ColorType | Sequence[ColorType] | None = None, ) -> None: ... + # XXX: Here the implementation relies on `fill` and `stroke` which are not + # in the interface of `GraphicsContextBase`. Here we use + # `GraphicsContextPdf` to annotate `gc`, as a result, `RendererPdf` does not + # strictly inherit from `RenderedBase` correctly. def draw_markers( - self, gc, marker_path, marker_trans, path, trans, rgbFace=None + self, + gc: GraphicsContextPdf, # type: ignore[override] + marker_path: path.Path, + marker_trans: Transform, + path: path.Path, + trans: Transform, + rgbFace: ColorType | None = None, + ) -> None: ... + def draw_gouraud_triangles( + self, + gc: GraphicsContextBase, + points: npt.ArrayLike, + colors: npt.ArrayLike, + trans: Transform, + ) -> None: ... + def draw_mathtext( + self, + gc: GraphicsContextBase, + x: float, + y: float, + s: str, + prop: FontProperties, + angle: float, + ) -> None: ... + def draw_tex( + self, + gc: GraphicsContextBase, + x: float, + y: float, + s: str, + prop: FontProperties, + angle: float, + *, + mtext: Text | None = None, ) -> None: ... - def draw_gouraud_triangles(self, gc, points, colors, trans) -> None: ... - def draw_mathtext(self, gc, x, y, s, prop, angle) -> None: ... - def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None) -> None: ... def encode_string(self, s: str, fonttype: int) -> bytes: ... def draw_text( - self, gc, x, y, s: str, prop, angle, ismath=False, mtext=None + self, + gc: GraphicsContextBase, + x: float, + y: float, + s: str, + prop: FontProperties, + angle: float, + ismath: bool | Literal["TeX"] = False, + mtext: Text | None = None, ) -> None: ... def new_gc(self) -> GraphicsContextPdf: ... -_Command: TypeAlias = list[_SupportsPdfReprExt] -_CommandFunction: TypeAlias = Callable[[GraphicsContextBase, Any, ...], _Command] - class GraphicsContextPdf(GraphicsContextBase): file: PdfFile - capstyles: dict[str, int] - joinstyles: dict[str, int] - commands: tuple[tuple[str, ...], _CommandFunction] - def __init__(self, file): ... - def __repr__(self): ... + capstyles: dict[CapStyleType, int] + joinstyles: dict[JoinStyleType, int] + commands: tuple[tuple[str, ...], _CommandFuncType] + def __init__(self, file: PdfFile): ... + def __repr__(self) -> str: ... def stroke(self) -> bool: ... - def fill(self, *args) -> bool: ... + def fill(self, *args: ColorType) -> bool: ... def paint(self) -> Op: ... - def capstyle_cmd(self, style: int) -> _Command: ... - def joinstyle_cmd(self, style) -> _Command: ... - def linewidth_cmd(self, width) -> _Command: ... + def capstyle_cmd(self, style: CapStyleType) -> _CommandType: ... + def joinstyle_cmd(self, style: JoinStyleType) -> _CommandType: ... + def linewidth_cmd(self, width: float) -> _CommandType: ... def dash_cmd( self, dashes: tuple[float, Iterable[_SupportsPdfReprExt]] - ) -> _Command: ... - # TODO: unable to determine types for unused `alpha`, `forced` - def alpha_cmd(self, alpha: int, forced: bool, effective_alphas) -> _Command: ... - def hatch_cmd(self, hatch, hatch_color, hatch_linewidth) -> _Command: ... - # TODO: determine type of `rgb[:]` - def rgb_cmd(self, rgb: list[int]) -> _Command: ... - def fillcolor_cmd(self, rgb: list[int]) -> _Command: ... + ) -> _CommandType: ... + def alpha_cmd( + self, alpha: int, forced: bool, effective_alphas: int + ) -> _CommandType: ... + def hatch_cmd( + self, hatch: _HatchType, hatch_color: ColorType, hatch_linewidth: float + ) -> _CommandType: ... + def rgb_cmd(self, rgb: RGBColorType) -> _CommandType: ... + def fillcolor_cmd(self, rgb: RGBColorType) -> _CommandType: ... def push(self) -> list[Op]: ... def pop(self) -> list[Op]: ... - def clip_cmd(self, cliprect, clippath) -> _Command: ... - def delta(self, other: GraphicsContextBase) -> _Command: ... + def clip_cmd( + self, cliprect: TransformedBbox, clippath: TransformedPath + ) -> _CommandType: ... + def delta(self, other: GraphicsContextBase) -> _CommandType: ... def copy_properties(self, other: GraphicsContextBase) -> None: ... def finalize(self) -> list[Op]: ... @@ -281,17 +398,18 @@ class PdfPages: def attach_note( self, text: _SupportsPdfReprExt, - positionRect: list[int | float] = [-100, -100, 0, 0], + positionRect: _RectangleType = [-100, -100, 0, 0], ) -> None: ... class FigureCanvasPdf(FigureCanvasBase): filetypes: dict[str, str] - def get_default_filetype(cls) -> str: ... + # FIXME: `get_default_filetype` does not inherit from `FigureCanvasBase` correctly + def get_default_filetype(cls) -> str: ... # type: ignore[override] def print_pdf( self, filename: PdfPages | IO[Any], *, - bbox_inches_restore: list[int | float] | None = None, + bbox_inches_restore: _RectangleType | None = None, metadata: _MetadataDict | None = None, ) -> None: ... def draw(self) -> None: ...