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

Skip to content

Commit de3b37a

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 de3b37a

File tree

1 file changed

+60
-3
lines changed

1 file changed

+60
-3
lines changed

lib/matplotlib/font_manager.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
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
@@ -536,6 +537,56 @@ def afmFontProperty(fontpath, font):
536537
return FontEntry(fontpath, name, style, variant, weight, stretch, size)
537538

538539

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

658+
@_cleanup_fontproperties_init
602659
def __init__(self, family=None, style=None, variant=None, weight=None,
603660
stretch=None, size=None,
604661
fname=None, # if set, it's a hardcoded filename to use

0 commit comments

Comments
 (0)