8000 Update type hints for font manager and extension · matplotlib/matplotlib@94146a1 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 94146a1

Browse files
committed
Update type hints for font manager and extension
1 parent 3ca6f23 commit 94146a1

File tree

8 files changed

+139
-97
lines changed

8 files changed

+139
-97
lines changed

ci/mypy-stubtest-allowlist.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ matplotlib.pylab.*
55
matplotlib._.*
66
matplotlib.rcsetup._listify_validator
77
matplotlib.rcsetup._validate_linestyle
8-
matplotlib.ft2font.*
8+
matplotlib.ft2font.Glyph
99
matplotlib.testing.jpl_units.*
1010
matplotlib.sphinxext.*
1111

lib/matplotlib/font_manager.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import subprocess
4141
import sys
4242
import threading
43+
from typing import Union
4344

4445
import matplotlib as mpl
4546
from matplotlib import _api, _afm, cbook, ft2font
@@ -315,7 +316,7 @@ def _fontentry_helper_repr_html(fontent):
315316
('name', str, dataclasses.field(default='')),
316317
('style', str, dataclasses.field(default='normal')),
317318
('variant', str, dataclasses.field(default='normal')),
318-
('weight', str, dataclasses.field(default='normal')),
319+
('weight', Union[str, int], dataclasses.field(default='normal')),
319320
('stretch', str, dataclasses.field(default='normal')),
320321
('size', str, dataclasses.field(default='medium')),
321322
],
@@ -464,6 +465,8 @@ def afmFontProperty(fontpath, font):
464465
465466
Parameters
466467
----------
468+
fontpath : str
469+
The filename corresponding to *font*.
467470
font : AFM
468471
The AFM font file from which information will be extracted.
469472

lib/matplotlib/font_manager.pyi

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,19 @@ X11FontDirectories: list[str]
2020
OSXFontDirectories: list[str]
2121

2222
def get_fontext_synonyms(fontext: str) -> list[str]: ...
23-
def list_fonts(directory: str, extensions: Iterable[str]): ...
23+
def list_fonts(directory: str, extensions: Iterable[str]) -> list[str]: ...
2424
def win32FontDirectory() -> str: ...
2525
def _get_fontconfig_fonts() -> list[Path]: ...
2626
def findSystemFonts(
27-
fontpaths: Iterable[str] | None = ..., fontext: str = ...
27+
fontpaths: Iterable[str | os.PathLike | Path] | None = ..., fontext: str = ...
2828
) -> list[str]: ...
2929
@dataclass
3030
class FontEntry:
3131
fname: str = ...
3232
name: str = ...
3333
style: str = ...
3434
variant: str = ...
35-
weight: str = ...
35+
weight: str | int = ...
3636
stretch: str = ...
3737
size: str = ...
3838

@@ -42,41 +42,44 @@ def afmFontProperty(fontpath: str, font: AFM) -> FontEntry: ...
4242
class FontProperties:
4343
def __init__(
4444
self,
45-
family: str | None = ...,
45+
family: str | Iterable[str] | None = ...,
4646
style: Literal["normal", "italic", "oblique"] | None = ...,
4747
variant: Literal["normal", "small-caps"] | None = ...,
4848
weight: int | str | None = ...,
4949
stretch: int | str | None = ...,
5050
size: float | str | None = ...,
51-
fname: str | None = ...,
51+
fname: str | os.PathLike | Path | None = ...,
5252
math_fontfamily: str | None = ...,
5353
) -> None: ...
5454
def __hash__(self) -> int: ...
5555
def __eq__(self, other: object) -> bool: ...
56-
def get_family(self) -> str: ...
56+
def get_family(self) -> list[str]: ...
5757
def get_name(self) -> str: ...
5858
def get_style(self) -> Literal["normal", "italic", "oblique"]: ...
5959
def get_variant(self) -> Literal["normal", "small-caps"]: ...
6060
def get_weight(self) -> int | str: ...
6161
def get_stretch(self) -> int | str: ...
6262
def get_size(self) -> float: ...
63-
def get_file(self) -> str: ...
63+
def get_file(self) -> str | bytes | None: ...
6464
def get_fontconfig_pattern(self) -> dict[str, list[Any]]: ...
65-
def set_family(self, family: str | Iterable[str]) -> None: ...
66-
def set_style(self, style: Literal["normal", "italic", "oblique"]) -> None: ...
67-
def set_variant(self, variant: Literal["normal", "small-caps"]) -> None: ...
68-
def set_weight(self, weight: int | str) -> None: ...
69-
def set_stretch(self, stretch: int | str) -> None: ...
70-
def set_size(self, size: float | str) -> None: ...
65+
def set_family(self, family: str | Iterable[str] | None) -> None: ...
66+
def set_style(
67+
self, style: Literal["normal", "italic", "oblique"] | None
68+
) -> None: ...
69+
def set_variant(self, variant: Literal["normal", "small-caps"] | None) -> None: ...
70+
def set_weight(self, weight: int | str | None) -> None: ...
71+
def set_stretch(self, stretch: int | str | None) -> None: ...
72+
def set_size(self, size: float | str | None) -> None: ...
7173
def set_file(self, file: str | os.PathLike | Path | None) -> None: ...
7274
def set_fontconfig_pattern(self, pattern: str) -> None: ...
7375
def get_math_fontfamily(self) -> str: ...
7476
def set_math_fontfamily(self, fontfamily: str | None) -> None: ...
7577
def copy(self) -> FontProperties: ...
76-
def set_name(self, family: str) -> None: ...
77-
def get_slant(self) -> Literal["normal", "italic", "oblique"]: ...
78-
def set_slant(self, style: Literal["normal", "italic", "oblique"]) -> None: ...
79-
def get_size_in_points(self) -> float: ...
78+
# Aliases
79+
set_name = set_family
80+
get_slant = get_style
81+
set_slant = set_style
82+
get_size_in_points = get_size
8083

8184
def json_dump(data: FontManager, filename: str | Path | os.PathLike) -> None: ...
8285
def json_load(filename: str | Path | os.PathLike) -> FontManager: ...

lib/matplotlib/ft2font.pyi

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
# This is generated from a compiled module, and as such is very generic
2-
# This could be more specific. Docstrings for this module are light
1+
from typing import BinaryIO, Literal
32

4-
from typing import Any
3+
import numpy as np
4+
from numpy.typing import NDArray
55

6+
__freetype_build_type__: str
7+
__freetype_version__: str
68
BOLD: int
79
EXTERNAL_STREAM: int
810
FAST_GLYPHS: int
@@ -41,54 +43,83 @@ SFNT: int
4143
VERTICAL: int
4244

4345
class FT2Font:
44-
ascender: Any
45-
bbox: Any
46-
descender: Any
47-
face_flags: Any
48-
family_name: Any
49-
fname: Any
50-
height: Any
51-
max_advance_height: Any
52-
max_advance_width: Any
53-
num_charmaps: Any
54-
num_faces: Any
55-
num_fixed_sizes: Any
56-
num_glyphs: Any
57-
postscript_name: Any
58-
scalable: Any
59-
style_flags: Any
60-
style_name: Any
61-
underline_position: Any
62-
underline_thickness: Any
63-
units_per_EM: Any
64-
def __init__(self, *args, **kwargs) -> None: ...
65-
def _get_fontmap(self, *args, **kwargs) -> Any: ...
66-
def clear(self, *args, **kwargs) -> Any: ...
67-
def draw_glyph_to_bitmap(self, *args, **kwargs) -> Any: ...
68-
def draw_glyphs_to_bitmap(self, *args, **kwargs) -> Any: ...
69-
def get_bitmap_offset(self, *args, **kwargs) -> Any: ...
70-
def get_char_index(self, *args, **kwargs) -> Any: ...
71-
def get_charmap(self, *args, **kwargs) -> Any: ...
72-
def get_descent(self, *args, **kwargs) -> Any: ...
73-
def get_glyph_name(self, *args, **kwargs) -> Any: ...
74-
def get_image(self, *args, **kwargs) -> Any: ...
75-
def get_kerning(self, *args, **kwargs) -> Any: ...
76-
def get_name_index(self, *args, **kwargs) -> Any: ...
77-
def get_num_glyphs(self, *args, **kwargs) -> Any: ...
78-
def get_path(self, *args, **kwargs) -> Any: ...
79-
def get_ps_font_info(self, *args, **kwargs) -> Any: ...
80-
def get_sfnt(self, *args, **kwargs) -> Any: ...
81-
def get_sfnt_table(self, *args, **kwargs) -> Any: ...
82-
def get_width_height(self, *args, **kwargs) -> Any: ...
83-
def get_xys(self, *args, **kwargs) -> Any: ...
84-
def load_char(self, *args, **kwargs) -> Any: ...
85-
def load_glyph(self, *args, **kwargs) -> Any: ...
86-
def select_charmap(self, *args, **kwargs) -> Any: ...
87-
def set_charmap(self, *args, **kwargs) -> Any: ...
88-
def set_size(self, *args, **kwargs) -> Any: ...
89-
def set_text(self, *args, **kwargs) -> Any: ...
46+
ascender: int
47+
bbox: tuple[int, int, int, int]
48+
descender: int
49+
face_flags: int
50+
family_name: str
51+
fname: str
52+
height: int
53+
max_advance_height: int
54+
max_advance_width: int
55+
num_charmaps: int
56+
num_faces: int
57+
num_fixed_sizes: int
58+
num_glyphs: int
59+
postscript_name: str
60+
scalable: bool
61+
style_flags: int
62+
style_name: str
63+
underline_position: int
64+
underline_thickness: int
65+
units_per_EM: int
9066

91-
class FT2Image:
92-
def __init__(self, *args, **kwargs) -> None: ...
93-
def draw_rect(self, *args, **kwargs) -> Any: ...
94-
def draw_rect_filled(self, *args, **kwargs) -> Any: ...
67+
def __init__(
68+
self,
69+
filename: str | BinaryIO,
70+
hinting_factor: int = ...,
71+
*,
72+
_fallback_list: list[FT2Font] | None = ...,
73+
_kerning_factor: int = ...
74+
) -> None: ...
75+
def _get_fontmap(self, string: str) -> dict[str, FT2Font]: ...
76+
def clear(self) -> None: ...
77+
def draw_glyph_to_bitmap(
78+
self, image: FT2Image, x: float, y: float, glyph: Glyph, antialiased: bool = ...
79+
) -> None: ...
80+
def draw_glyphs_to_bitmap(self, antialiased: bool = ...) -> None: ...
81+
def get_bitmap_offset(self) -> tuple[int, int]: ...
82+
def get_char_index(self, codepoint: int) -> int: ...
83+
def get_charmap(self) -> dict[int, int]: ...
84+
def get_descent(self) -> int: ...
85+
def get_glyph_name(self, index: int) -> str: ...
86+
def get_image(self) -> NDArray[np.uint8]: ...
87+
def get_kerning(self, left: int, right: int, mode: int) -> int: ...
88+
def get_name_index(self, name: str) -> int: ...
89+
def get_num_glyphs(self) -> int: ...
90+
def get_path(self) -> tuple[NDArray[np.float64], NDArray[np.int8]]: ...
91+
def get_ps_font_info(
92+
self,
93+
) -> tuple[str, str, str, str, str, int, int, int, int]: ...
94+
def get_sfnt(self) -> dict[tuple[int, int, int, int], bytes]: ...
95+
def get_sfnt_table(
96+
self, name: Literal["head", "maxp", "OS/2", "hhea", "vhea", "post", "pclt"]
97+
) -> dict[str, tuple[int, int, int, int] | tuple[int, int] | int | bytes]: ...
98+
def get_width_height(self) -> tuple[int, int]: ...
99+
def get_xys(self, antialiased: bool = ...) -> NDArray[np.float64]: ...
100+
def load_char(self, charcode: int, flags: int = ...) -> Glyph: ...
101+
def load_glyph(self, glyphindex: int, flags: int = ...) -> Glyph: ...
102+
def select_charmap(self, i: int) -> None: ...
103+
def set_charmap(self, i: int) -> None: ...
104+
def set_size(self, ptsize: float, dpi: float) -> None: ...
105+
def set_text(
106+
self, string: str, angle: float = ..., flags: int = ...
107+
) -> NDArray[np.float64]: ...
108+
109+
class FT2Image: # TODO: When updating mypy>=1.4, subclass from Buffer.
110+
def __init__(self, width: float, height: float) -> None: ...
111+
def draw_rect(self, x0: float, y0: float, x1: float, y1: float) -> None: ...
112+
def draw_rect_filled(self, x0: float, y0: float, x1: float, y1: float) -> None: ...
113+
114+
class Glyph:
115+
width: int
116+
height: int
117+
horiBearingX: int
118+
horiBearingY: int
119+
horiAdvance: int
120+
linearHoriAdvance: int
121+
vertBearingX: int
122+
vertBearingY: int
123+
vertAdvance: int
124+
125+
def bbox(self) -> tuple[int, int, int, int]: ...

lib/matplotlib/tests/test_font_manager.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ def test_font_priority():
2525
with rc_context(rc={
2626
'font.sans-serif':
2727
['cmmi10', 'Bitstream Vera Sans']}):
28-
font = findfont(FontProperties(family=["sans-serif"]))
29-
assert Path(font).name == 'cmmi10.ttf'
28+
fontfile = findfont(FontProperties(family=["sans-serif"]))
29+
assert Path(fontfile).name == 'cmmi10.ttf'
3030

3131
# Smoketest get_charmap, which isn't used internally anymore
32-
font = get_font(font)
32+
font = get_font(fontfile)
3333
cmap = font.get_charmap()
3434
assert len(cmap) == 131
3535
assert cmap[8729] == 30
@@ -148,7 +148,7 @@ def test_find_invalid(tmpdir):
148148
# Not really public, but get_font doesn't expose non-filename constructor.
149149
from matplotlib.ft2font import FT2Font
150150
with pytest.raises(TypeError, match='font file or a binary-mode file'):
151-
FT2Font(StringIO())
151+
FT2Font(StringIO()) # type: ignore[arg-type]
152152

153153

154154
@pytest.mark.skipif(sys.platform != 'linux' or not has_fclist,

lib/matplotlib/tests/test_ft2font.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ def test_fallback_errors():
1414

1515
with pytest.raises(TypeError, match="Fallback list must be a list"):
1616
# failing to be a list will fail before the 0
17-
ft2font.FT2Font(file_name, _fallback_list=(0,))
17+
ft2font.FT2Font(file_name, _fallback_list=(0,)) # type: ignore[arg-type]
1818

1919
with pytest.raises(
2020
TypeError, match="Fallback fonts must be FT2Font objects."
2121
):
22-
ft2font.FT2Font(file_name, _fallback_list=[0])
22+
ft2font.FT2Font(file_name, _fallback_list=[0]) # type: ignore[list-item]
2323

2424

2525
def test_ft2font_positive_hinting_factor():

lib/matplotlib/tests/test_mathtext.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
font_tests: list[None | str] = []
183183
for fonts, chars in font_test_specs:
184184
if fonts is None:
185-
font_tests.extend([None] * chars) # type: ignore
185+
font_tests.extend([None] * chars)
186186
else:
187187
wrapper = ''.join([
188188
' '.join(fonts),

src/ft2font_wrapper.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -331,46 +331,51 @@ const char *PyFT2Font_init__doc__ =
331331
"Parameters\n"
332332
"----------\n"
333333
"filename : str or file-like\n"
334-
" The source of the font data in a format (ttf or ttc) that FreeType can read\n\n"
334+
" The source of the font data in a format (ttf or ttc) that FreeType can read\n"
335+
"\n"
335336
"hinting_factor : int, optional\n"
336337
" Must be positive. Used to scale the hinting in the x-direction\n"
337338
"_fallback_list : list of FT2Font, optional\n"
338-
" A list of FT2Font objects used to find missing glyphs.\n\n"
339+
" A list of FT2Font objects used to find missing glyphs.\n"
340+
"\n"
339341
" .. warning::\n"
340-
" This API is both private and provisional: do not use it directly\n\n"
342+
" This API is both private and provisional: do not use it directly\n"
343+
"\n"
341344
"_kerning_factor : int, optional\n"
342-
" Used to adjust the degree of kerning.\n\n"
345+
" Used to adjust the degree of kerning.\n"
346+
"\n"
343347
" .. warning::\n"
344-
" This API is private: do not use it directly\n\n"
348+
" This API is private: do not use it directly\n"
349+
"\n"
345350
"Attributes\n"
346351
"----------\n"
347-
"num_faces\n"
352+
"num_faces : int\n"
348353
" Number of faces in file.\n"
349354
"face_flags, style_flags : int\n"
350355
" Face and style flags; see the ft2font constants.\n"
351-
"num_glyphs\n"
356+
"num_glyphs : int\n"
352357
" Number of glyphs in the face.\n"
353-
"family_name, style_name\n"
358+
"family_name, style_name : str\n"
354359
" Face family and style name.\n"
355-
"num_fixed_sizes\n"
360+
"num_fixed_sizes : int\n"
356361
" Number of bitmap in the face.\n"
357-
"scalable\n"
362+
"scalable : bool\n"
358363
" Whether face is scalable; attributes after this one are only\n"
359364
" defined for scalable faces.\n"
360-
"bbox\n"
365+
"bbox : tuple[int, int, int, int]\n"
361366
" Face global bounding box (xmin, ymin, xmax, ymax).\n"
362-
"units_per_EM\n"
367+
"units_per_EM : int\n"
363368
" Number of font units covered by the EM.\n"
364-
"ascender, descender\n"
369+
"ascender, descender : int\n"
365370
" Ascender and descender in 26.6 units.\n"
366-
"height\n"
371+
"height : int\n"
367372
" Height in 26.6 units; used to compute a default line spacing\n"
368373
" (baseline-to-baseline distance).\n"
369-
"max_advance_width, max_advance_height\n"
374+
"max_advance_width, max_advance_height : int\n"
370375
" Maximum horizontal and vertical cursor advance for all glyphs.\n"
371-
"underline_position, underline_thickness\n"
376+
"underline_position, underline_thickness : int\n"
372377
" Vertical position and thickness of the underline bar.\n"
373-
"postscript_name\n"
378+
"postscript_name : str\n"
374379
" PostScript name of the font.\n";
375380

376381
static int PyFT2Font_init(PyFT2Font *self, PyObject *args, PyObject *kwds)
@@ -627,7 +632,7 @@ static PyObject *PyFT2Font_get_fontmap(PyFT2Font *self, PyObject *args, PyObject
627632

628633

629634
const char *PyFT2Font_set_text__doc__ =
630-
"set_text(self, string, angle, flags=32)\n"
635+
"set_text(self, string, angle=0.0, flags=32)\n"
631636
"--\n\n"
632637
"Set the text *string* and *angle*.\n"
633638
"*flags* can be a bitwise-or of the LOAD_XXX constants;\n"

0 commit comments

Comments
 (0)
0