Merge pull request #31879 from QuLogic/remove-deprecations · matplotlib/matplotlib@bde111f · GitHub
Skip to content

Commit bde111f

Browse files
authored
Merge pull request #31879 from QuLogic/remove-deprecations
MNT: Remove font-related deprecations from 3.10
2 parents d6c3639 + 173fdf9 commit bde111f

7 files changed

Lines changed: 108 additions & 328 deletions

File tree

Lines changed: 79 additions & 0 deletions

lib/matplotlib/font_manager.py

Lines changed: 12 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
from base64 import b64encode
3131
import dataclasses
3232
from functools import cache, lru_cache
33-
import functools
3433
from io import BytesIO
3534
import json
3635
import logging
@@ -695,57 +694,6 @@ def afmFontProperty(fontpath, font):
695694
return FontEntry(fontpath, 0, name, style, variant, weight, stretch, size)
696695

697696

698-
def _cleanup_fontproperties_init(init_method):
699-
"""
700-
A decorator to limit the call signature to a single positional argument
701-
or alternatively only keyword arguments.
702-
703-
We still accept but deprecate all other call signatures.
704-
705-
When the deprecation expires we can switch the signature to::
706-
707-
__init__(self, pattern=None, /, *, family=None, style=None, ...)
708-
709-
plus a runtime check that pattern is not used alongside with the
710-
keyword arguments. This results eventually in the two possible
711-
call signatures::
712-
713-
FontProperties(pattern)
714-
FontProperties(family=..., size=..., ...)
715-
716-
"""
717-
@functools.wraps(init_method)
718-
def wrapper(self, *args, **kwargs):
719-
# multiple args with at least some positional ones
720-
if len(args) > 1 or len(args) == 1 and kwargs:
721-
# Note: Both cases were previously handled as individual properties.
722-
# Therefore, we do not mention the case of font properties here.
723-
_api.warn_deprecated(
724-
"3.10",
725-
message="Passing individual properties to FontProperties() "
726-
"positionally was deprecated in Matplotlib %(since)s and "
727-
"will be removed in %(removal)s. Please pass all properties "
728-
"via keyword arguments."
729-
)
730-
# single non-string arg -> clearly a family not a pattern
731-
if len(args) == 1 and not kwargs and not cbook.is_scalar_or_string(args[0]):
732-
# Case font-family list passed as single argument
733-
_api.warn_deprecated(
734-
"3.10",
735-
message="Passing family as positional argument to FontProperties() "
736-
"was deprecated in Matplotlib %(since)s and will be removed "
737-
"in %(removal)s. Please pass family names as keyword"
738-
"argument."
739-
)
740-
# Note on single string arg:
741-
# This has been interpreted as pattern so far. We are already raising if a
742-
# non-pattern compatible family string was given. Therefore, we do not need
743-
# to warn for this case.
744-
return init_method(self, *args, **kwargs)
745-
746-
return wrapper
747-
748-
749697
class FontProperties:
750698
"""
751699
A class for storing and manipulating font properties.
@@ -814,11 +762,17 @@ class FontProperties:
814762
fontconfig.
815763
"""
816764

817-
@_cleanup_fontproperties_init
818-
def __init__(self, family=None, style=None, variant=None, weight=None,
765+
def __init__(self, pattern=None, /, *,
766+
family=None, style=None, variant=None, weight=None,
819767
stretch=None, size=None,
820768
fname=None, # if set, it's a hardcoded filename to use
821769
math_fontfamily=None):
770+
if pattern is not None:
771+
if not (family is None and style is None and variant is None and
772+
weight is None and stretch is None and size is None and
773+
fname is None):
774+
raise TypeError("Passing both a fontconfig pattern and individual "
775+
"properties to FontProperties() is invalid")
822776
self.set_family(family)
823777
self.set_style(style)
824778
self.set_variant(variant)
@@ -827,13 +781,10 @@ def __init__(self, family=None, style=None, variant=None, weight=None,
827781
self.set_file(fname)
828782
self.set_size(size)
829783
self.set_math_fontfamily(math_fontfamily)
830-
# Treat family as a fontconfig pattern if it is the only parameter
831-
# provided. Even in that case, call the other setters first to set
832-
# attributes not specified by the pattern to the rcParams defaults.
833-
if (isinstance(family, str)
834-
and style is None and variant is None and weight is None
835-
and stretch is None and size is None and fname is None):
836-
self.set_fontconfig_pattern(family)
784+
# Even in the case a fontconfig pattern is provided, call the other setters
785+
# first to set attributes not specified by the pattern to the rcParams defaults.
786+
if pattern is not None:
787+
self.set_fontconfig_pattern(pattern)
837788

838789
@classmethod
839790
def _from_any(cls, arg):

lib/matplotlib/font_manager.pyi

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ from dataclasses import dataclass
33
from numbers import Integral
44
import os
55
from pathlib import Path
6-
from typing import Any, Final, Literal
6+
from typing import Any, Final, Literal, overload
77

88
from matplotlib._afm import AFM
99
from matplotlib import ft2font
@@ -62,8 +62,11 @@ def ttfFontProperty(font: ft2font.FT2Font) -> FontEntry: ...
6262
def afmFontProperty(fontpath: str, font: AFM) -> FontEntry: ...
6363

6464
class FontProperties:
65+
@overload
66+
def __init__(self, pattern: str | None, /) -> None: ...
67+
@overload
6568
def __init__(
66-
self,
69+
self, *,
6770
family: str | Iterable[str] | None = ...,
6871
style: Literal["normal", "italic", "oblique"] | None = ...,
6972
variant: Literal["normal", "small-caps"] | None = ...,

lib/matplotlib/tests/test_font_manager.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -564,35 +564,23 @@ def test_fontproperties_init_deprecation():
564564
which calls do and do not issue deprecation warnings. Behavior is still
565565
tested via the existing regular tests.
566566
"""
567-
with pytest.warns(mpl.MatplotlibDeprecationWarning):
567+
with pytest.raises(TypeError):
568568
# multiple positional arguments
569569
FontProperties("Times", "italic")
570570

571-
with pytest.warns(mpl.MatplotlibDeprecationWarning):
571+
with pytest.raises(TypeError):
572572
# Mixed positional and keyword arguments
573573
FontProperties("Times", size=10)
574574

575-
with pytest.warns(mpl.MatplotlibDeprecationWarning):
575+
with pytest.raises(TypeError):
576576
# passing a family list positionally
577577
FontProperties(["Times"])
578578

579579
# still accepted:
580580
FontProperties(family="Times", style="italic")
581581
FontProperties(family="Times")
582-
FontProperties("Times") # works as pattern and family
583582
FontProperties("serif-24:style=oblique:weight=bold") # pattern
584583

585-
# also still accepted:
586-
# passing as pattern via family kwarg was not covered by the docs but
587-
# historically worked. This is left unchanged for now.
588-
# AFAICT, we cannot detect this: We can determine whether a string
589-
# works as pattern, but that doesn't help, because there are strings
590-
# that are both pattern and family. We would need to identify, whether
591-
# a string is *not* a valid family.
592-
# Since this case is not covered by docs, I've refrained from jumping
593-
# extra hoops to detect this possible API misuse.
594-
FontProperties(family="serif-24:style=oblique:weight=bold")
595-
596584

597585
def test_normalize_weights():
598586
assert _normalize_weight(300) == 300 # passthrough

lib/matplotlib/tests/test_ft2font.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -839,30 +839,6 @@ def test_ft2font_get_kerning(left, right, unscaled, unfitted, default):
839839
assert font.get_kerning(font.get_char_index(ord(left)),
840840
font.get_char_index(ord(right)),
841841
ft2font.Kerning.DEFAULT) == default
842-
with pytest.warns(mpl.MatplotlibDeprecationWarning,
843-
match='Use Kerning.UNSCALED instead'):
844-
k = ft2font.KERNING_UNSCALED
845-
with pytest.warns(mpl.MatplotlibDeprecationWarning,
846-
match='Use Kerning enum values instead'):
847-
assert font.get_kerning(font.get_char_index(ord(left)),
848-
font.get_char_index(ord(right)),
849-
int(k)) == unscaled
850-
with pytest.warns(mpl.MatplotlibDeprecationWarning,
851-
match='Use Kerning.UNFITTED instead'):
852-
k = ft2font.KERNING_UNFITTED
853-
with pytest.warns(mpl.MatplotlibDeprecationWarning,
854-
match='Use Kerning enum values instead'):
855-
assert font.get_kerning(font.get_char_index(ord(left)),
856-
font.get_char_index(ord(right)),
857-
int(k)) == unfitted
858-
with pytest.warns(mpl.MatplotlibDeprecationWarning,
859-
match='Use Kerning.DEFAULT instead'):
860-
k = ft2font.KERNING_DEFAULT
861-
with pytest.warns(mpl.MatplotlibDeprecationWarning,
862-
match='Use Kerning enum values instead'):
863-
assert font.get_kerning(font.get_char_index(ord(left)),
864-
font.get_char_index(ord(right)),
865-
int(k)) == default
866842

867843

868844
def test_ft2font_set_text():

src/_backend_agg_wrapper.cpp

Lines changed: 1 addition & 30 deletions

0 commit comments

Comments
 (0)