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

Skip to content

Commit c447b60

Browse files
authored
Merge pull request #27415 from QuLogic/dataclass-class
Use class form of data classes
2 parents d90e290 + 5e5962f commit c447b60

File tree

5 files changed

+60
-60
lines changed

5 files changed

+60
-60
lines changed

doc/api/font_manager_api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
.. automodule:: matplotlib.font_manager
66
:members:
7+
:exclude-members: FontEntry
78
:undoc-members:
89
:show-inheritance:
910

galleries/examples/widgets/menu.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@
55
66
Using texts to construct a simple menu.
77
"""
8+
9+
from dataclasses import dataclass
10+
811
import matplotlib.pyplot as plt
912

1013
import matplotlib.artist as artist
1114
import matplotlib.patches as patches
15+
from matplotlib.typing import ColorType
1216

1317

18+
@dataclass
1419
class ItemProperties:
15-
def __init__(self, fontsize=14, labelcolor='black', bgcolor='yellow',
16-
alpha=1.0):
17-
self.fontsize = fontsize
18-
self.labelcolor = labelcolor
19-
self.bgcolor = bgcolor
20-
self.alpha = alpha
20+
fontsize: float = 14
21+
labelcolor: ColorType = 'black'
22+
bgcolor: ColorType = 'yellow'
23+
alpha: float = 1.0
2124

2225

2326
class MenuItem(artist.Artist):
@@ -130,7 +133,7 @@ def on_move(self, event):
130133
menuitems = []
131134
for label in ('open', 'close', 'save', 'save as', 'quit'):
132135
def on_select(item):
133-
print('you selected %s' % item.labelstr)
136+
print(f'you selected {item.labelstr}')
134137
item = MenuItem(fig, label, props=props, hoverprops=hoverprops,
135138
on_select=on_select)
136139
menuitems.append(item)

lib/matplotlib/_text_helpers.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22
Low-level text helper utilities.
33
"""
44

5+
from __future__ import annotations
6+
57
import dataclasses
68

79
from . import _api
8-
from .ft2font import KERNING_DEFAULT, LOAD_NO_HINTING
10+
from .ft2font import KERNING_DEFAULT, LOAD_NO_HINTING, FT2Font
911

1012

11-
LayoutItem = dataclasses.make_dataclass(
12-
"LayoutItem", ["ft_object", "char", "glyph_idx", "x", "prev_kern"])
13+
@dataclasses.dataclass(frozen=True)
14+
class LayoutItem:
15+
ft_object: FT2Font
16+
char: str
17+
glyph_idx: int
18+
x: float
19+
prev_kern: float
1320

1421

1522
def warn_on_missing_glyph(codepoint, fontnames):
@@ -38,9 +45,10 @@ def warn_on_missing_glyph(codepoint, fontnames):
3845

3946
def layout(string, font, *, kern_mode=KERNING_DEFAULT):
4047
"""
41-
Render *string* with *font*. For each character in *string*, yield a
42-
(glyph-index, x-position) pair. When such a pair is yielded, the font's
43-
glyph is set to the corresponding character.
48+
Render *string* with *font*.
49+
50+
For each character in *string*, yield a LayoutItem instance. When such an instance
51+
is yielded, the font's glyph is set to the corresponding character.
4452
4553
Parameters
4654
----------
@@ -53,8 +61,7 @@ def layout(string, font, *, kern_mode=KERNING_DEFAULT):
5361
5462
Yields
5563
------
56-
glyph_index : int
57-
x_position : float
64+
LayoutItem
5865
"""
5966
x = 0
6067
prev_glyph_idx = None

lib/matplotlib/backends/backend_pdf.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,8 +2378,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23782378
multibyte_glyphs = []
23792379
prev_was_multibyte = True
23802380
prev_font = font
2381-
for item in _text_helpers.layout(
2382-
s, font, kern_mode=KERNING_UNFITTED):
2381+
for item in _text_helpers.layout(s, font, kern_mode=KERNING_UNFITTED):
23832382
if _font_supports_glyph(fonttype, ord(item.char)):
23842383
if prev_was_multibyte or item.ft_object != prev_font:
23852384
singlebyte_chunks.append((item.ft_object, item.x, []))
@@ -2389,9 +2388,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23892388
singlebyte_chunks[-1][2].append(item.char)
23902389
prev_was_multibyte = False
23912390
else:
2392-
multibyte_glyphs.append(
2393-
(item.ft_object, item.x, item.glyph_idx)
2394-
)
2391+
multibyte_glyphs.append((item.ft_object, item.x, item.glyph_idx))
23952392
prev_was_multibyte = True
23962393
# Do the rotation and global translation as a single matrix
23972394
# concatenation up front

lib/matplotlib/font_manager.py

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
# - setWeights function needs improvement
2626
# - 'light' is an invalid weight value, remove it.
2727

28+
from __future__ import annotations
29+
2830
from base64 import b64encode
2931
from collections import namedtuple
3032
import copy
@@ -41,7 +43,6 @@
4143
import subprocess
4244
import sys
4345
import threading
44-
from typing import Union
4546

4647
import matplotlib as mpl
4748
from matplotlib import _api, _afm, cbook, ft2font
@@ -304,42 +305,35 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
304305
return [fname for fname in fontfiles if os.path.exists(fname)]
305306

306307

307-
def _fontentry_helper_repr_png(fontent):
308-
from matplotlib.figure import Figure # Circular import.
309-
fig = Figure()
310-
font_path = Path(fontent.fname) if fontent.fname != '' else None
311-
fig.text(0, 0, fontent.name, font=font_path)
312-
with BytesIO() as buf:
313-
fig.savefig(buf, bbox_inches='tight', transparent=True)
314-
return buf.getvalue()
315-
316-
317-
def _fontentry_helper_repr_html(fontent):
318-
png_stream = _fontentry_helper_repr_png(fontent)
319-
png_b64 = b64encode(png_stream).decode()
320-
return f"<img src=\"data:image/png;base64, {png_b64}\" />"
321-
322-
323-
FontEntry = dataclasses.make_dataclass(
324-
'FontEntry', [
325-
('fname', str, dataclasses.field(default='')),
326-
('name', str, dataclasses.field(default='')),
327-
('style', str, dataclasses.field(default='normal')),
328-
('variant', str, dataclasses.field(default='normal')),
329-
('weight', Union[str, int], dataclasses.field(default='normal')),
330-
('stretch', str, dataclasses.field(default='normal')),
331-
('size', str, dataclasses.field(default='medium')),
332-
],
333-
namespace={
334-
'__doc__': """
308+
@dataclasses.dataclass(frozen=True)
309+
class FontEntry:
310+
"""
335311
A class for storing Font properties.
336312
337313
It is used when populating the font lookup dictionary.
338-
""",
339-
'_repr_html_': lambda self: _fontentry_helper_repr_html(self),
340-
'_repr_png_': lambda self: _fontentry_helper_repr_png(self),
341-
}
342-
)
314+
"""
315+
316+
fname: str = ''
317+
name: str = ''
318+
style: str = 'normal'
319+
variant: str = 'normal'
320+
weight: str | int = 'normal'
321+
stretch: str = 'normal'
322+
size: str = 'medium'
323+
324+
def _repr_html_(self) -> str:
325+
png_stream = self._repr_png_()
326+
png_b64 = b64encode(png_stream).decode()
327+
return f"<img src=\"data:image/png;base64, {png_b64}\" />"
328+
329+
def _repr_png_(self) -> bytes:
330+
from matplotlib.figure import Figure # Circular import.
331+
fig = Figure()
332+
font_path = Path(self.fname) if self.fname != '' else None
333+
fig.text(0, 0, self.name, font=font_path)
334+
with BytesIO() as buf:
335+
fig.savefig(buf, bbox_inches='tight', transparent=True)
336+
return buf.getvalue()
343337

344338

345339
def ttfFontProperty(font):
@@ -926,8 +920,7 @@ def default(self, o):
926920
try:
927921
# Cache paths of fonts shipped with Matplotlib relative to the
928922
# Matplotlib data path, which helps in the presence of venvs.
929-
d["fname"] = str(
930-
Path(d["fname"]).relative_to(mpl.get_data_path()))
923+
d["fname"] = str(Path(d["fname"]).relative_to(mpl.get_data_path()))
931924
except ValueError:
932925
pass
933926
return d
@@ -944,10 +937,9 @@ def _json_decode(o):
944937
r.__dict__.update(o)
945938
return r
946939
elif cls == 'FontEntry':
947-
r = FontEntry.__new__(FontEntry)
948-
r.__dict__.update(o)
949-
if not os.path.isabs(r.fname):
950-
r.fname = os.path.join(mpl.get_data_path(), r.fname)
940+
if not os.path.isabs(o['fname']):
941+
o['fname'] = os.path.join(mpl.get_data_path(), o['fname'])
942+
r = FontEntry(**o)
951943
return r
952944
else:
953945
raise ValueError("Don't know how to deserialize __class__=%s" % cls)

0 commit comments

Comments
 (0)