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

Skip to content

Commit b191200

Browse files
committed
MNT: Cleanup FontProperties __init__ API
The cleanup approach is to not modify code logic during a deprecation period, but only detect deprecated call patterns through a decorator and warn on them.
1 parent 5a0cdf1 commit b191200

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FontProperties initialization
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
`.FontProperties.` initialization is limited to the two call patterns:
5+
6+
- single positional parameter, interpreted as fontconfig pattern
7+
- only keyword parameters for setting individual properties
8+
9+
All other previously supported call patterns are deprecated.

lib/matplotlib/font_manager.py

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929

3030
from base64 import b64encode
3131
from collections import namedtuple
32+
from collections.abc import Iterable
3233
import copy
3334
import dataclasses
3435
from functools import lru_cache
36+
import functools
3537
from io import BytesIO
3638
import json
3739
import logging
@@ -536,6 +538,56 @@ def afmFontProperty(fontpath, font):
536538
return FontEntry(fontpath, name, style, variant, weight, stretch, size)
537539

538540

541+
def _cleanup_fontproperties_init(init_method):
542+
"""
543+
A decorator to limit the call signature to single a positional argument
544+
or alternatively only keyword arguments.
545+
546+
We still accept but deprecate all other call signatures.
547+
548+
When the deprecation expires we can switch the signature to::
549+
550+
__init__(self, pattern=None, /, *, family=None, style=None, ...)
551+
552+
plus a runtime check that pattern is not used alongside with the
553+
keyword arguments. This results eventually in the two possible
554+
call signatures::
555+
556+
FontProperties(pattern)
557+
FontProperties(family=..., size=..., ...)
558+
559+
"""
560+
@functools.wraps(init_method)
561+
def wrapper(self, *args, **kwargs):
562+
# multiple args with at least some positional ones
563+
if len(args) > 1 or len(args) == 1 and kwargs:
564+
# Note: Both cases were previously handled as individual properties.
565+
# Therefore, we do not mention the case of font properties here.
566+
_api.warn_deprecated(
567+
"3.10",
568+
message="Passing individual properties to FontProperties() "
569+
"positionally is deprecated. Please pass all properties "
570+
"via keyword arguments."
571+
)
572+
# single non-string arg -> clearly a family not a pattern
573+
if (len(args) == 1 and not kwargs
574+
and isinstance(args[0], Iterable) and not isinstance(args[0], str)):
575+
# Case font-family list passed as single argument
576+
_api.warn_deprecated(
577+
"3.10",
578+
message="Passing family as positional argument to FontProperties() "
579+
"is deprecated. Please pass family names as keyword"
580+
"argument."
581+
)
582+
# Note on single string arg:
583+
# This has been interpreted as pattern so far. We are already raising if a
584+
# non-pattern compatible family string was given. Therefore, we do not need
585+
# to warn for this case.
586+
return init_method(self, *args, **kwargs)
587+
588+
return wrapper
589+
590+
539591
class FontProperties:
540592
"""
541593
A class for storing and manipulating font properties.
@@ -585,9 +637,14 @@ class FontProperties:
585637
approach allows all text sizes to be made larger or smaller based
586638
on the font manager's default font size.
587639
588-
This class will also accept a fontconfig_ pattern_, if it is the only
589-
argument provided. This support does not depend on fontconfig; we are
590-
merely borrowing its pattern syntax for use here.
640+
This class accepts a single positional string as fontconfig_ pattern_,
641+
or alternatively individual properties as keyword arguments::
642+
643+
FontProperties(pattern)
644+
FontProperties(*, family=None, style=None, variant=None, ...)
645+
646+
This support does not depend on fontconfig; we are merely borrowing its
647+
pattern syntax for use here.
591648
592649
.. _fontconfig: https://www.freedesktop.org/wiki/Software/fontconfig/
593650
.. _pattern:
@@ -599,6 +656,7 @@ class FontProperties:
599656
fontconfig.
600657
"""
601658

659+
@_cleanup_fontproperties_init
602660
def __init__(self, family=None, style=None, variant=None, weight=None,
603661
stretch=None, size=None,
604662
fname=None, # if set, it's a hardcoded filename to use

lib/matplotlib/ticker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ def set_useMathText(self, val):
574574
from matplotlib import font_manager
575575
ufont = font_manager.findfont(
576576
font_manager.FontProperties(
577-
mpl.rcParams["font.family"]
577+
family=mpl.rcParams["font.family"]
578578
),
579579
fallback_to_default=False,
580580
)

0 commit comments

Comments
 (0)