| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff 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. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -32,6 +32,7 @@ | |||
| 32 | 32 | import copy | |
| 33 | 33 | import dataclasses | |
| 34 | 34 | from functools import lru_cache | |
| 35 | + import functools | ||
| 35 | 36 | from io import BytesIO | |
| 36 | 37 | import json | |
| 37 | 38 | import logging | |
@@ -536,6 +537,57 @@ def afmFontProperty(fontpath, font): | |||
| 536 | 537 | return FontEntry(fontpath, name, style, variant, weight, stretch, size) | |
| 537 | 538 | ||
| 538 | 539 | ||
| 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 wrapper(self, *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 | + message="Passing individual properties to FontProperties() " | ||
| 568 | + "positionally was deprecated in Matplotlib %(since)s and " | ||
| 569 | + "will be removed in %(removal)s. 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 and not cbook.is_scalar_or_string(args[0]): | ||
| 574 | + # Case font-family list passed as single argument | ||
| 575 | + _api.warn_deprecated( | ||
| 576 | + "3.10", | ||
| 577 | + message="Passing family as positional argument to FontProperties() " | ||
| 578 | + "was deprecated in Matplotlib %(since)s and will be removed " | ||
| 579 | + "in %(removal)s. 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 | + | ||
| 539 | 591 | class FontProperties: | |
| 540 | 592 | """ | |
| 541 | 593 | A class for storing and manipulating font properties. | |
@@ -585,9 +637,14 @@ class FontProperties: | |||
| 585 | 637 | approach allows all text sizes to be made larger or smaller based | |
| 586 | 638 | on the font manager's default font size. | |
| 587 | 639 | ||
| 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. | ||
| 591 | 648 | ||
| 592 | 649 | .. _fontconfig: https://www.freedesktop.org/wiki/Software/fontconfig/ | |
| 593 | 650 | .. _pattern: | |
@@ -599,6 +656,7 @@ class FontProperties: | |||
| 599 | 656 | fontconfig. | |
| 600 | 657 | """ | |
| 601 | 658 | ||
| 659 | + @_cleanup_fontproperties_init | ||
| 602 | 660 | def __init__(self, family=None, style=None, variant=None, weight=None, | |
| 603 | 661 | stretch=None, size=None, | |
| 604 | 662 | fname=None, # if set, it's a hardcoded filename to use | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | import numpy as np | |
| 12 | 12 | import pytest | |
| 13 | 13 | ||
| 14 | + import matplotlib as mpl | ||
| 14 | 15 | from matplotlib.font_manager import ( | |
| 15 | 16 | findfont, findSystemFonts, FontEntry, FontProperties, fontManager, | |
| 16 | 17 | json_dump, json_load, get_font, is_opentype_cff_font, | |
@@ -367,3 +368,42 @@ def inner(): | |||
| 367 | 368 | for obj in gc.get_objects(): | |
| 368 | 369 | if isinstance(obj, SomeObject): | |
| 369 | 370 | pytest.fail("object from inner stack still alive") | |
| 371 | + | ||
| 372 | + | ||
| 373 | + def test_fontproperties_init_deprecation(): | ||
| 374 | + """ | ||
| 375 | + Test the deprecated API of FontProperties.__init__. | ||
| 376 | + | ||
| 377 | + The deprecation does not change behavior, it only adds a deprecation warning | ||
| 378 | + via a decorator. Therefore, the purpose of this test is limited to check | ||
| 379 | + which calls do and do not issue deprecation warnings. Behavior is still | ||
| 380 | + tested via the existing regular tests. | ||
| 381 | + """ | ||
| 382 | + with pytest.warns(mpl.MatplotlibDeprecationWarning): | ||
| 383 | + # multiple positional arguments | ||
| 384 | + FontProperties("Times", "italic") | ||
| 385 | + | ||
| 386 | + with pytest.warns(mpl.MatplotlibDeprecationWarning): | ||
| 387 | + # Mixed positional and keyword arguments | ||
| 388 | + FontProperties("Times", size=10) | ||
| 389 | + | ||
| 390 | + with pytest.warns(mpl.MatplotlibDeprecationWarning): | ||
| 391 | + # passing a family list positionally | ||
| 392 | + FontProperties(["Times"]) | ||
| 393 | + | ||
| 394 | + # still accepted: | ||
| 395 | + FontProperties(family="Times", style="italic") | ||
| 396 | + FontProperties(family="Times") | ||
| 397 | + FontProperties("Times") # works as pattern and family | ||
| 398 | + FontProperties("serif-24:style=oblique:weight=bold") # pattern | ||
| 399 | + | ||
| 400 | + # also still accepted: | ||
| 401 | + # passing as pattern via family kwarg was not covered by the docs but | ||
| 402 | + # historically worked. This is left unchanged for now. | ||
| 403 | + # AFAICT, we cannot detect this: We can determine whether a string | ||
| 404 | + # works as pattern, but that doesn't help, because there are strings | ||
| 405 | + # that are both pattern and family. We would need to identify, whether | ||
| 406 | + # a string is *not* a valid family. | ||
| 407 | + # Since this case is not covered by docs, I've refrained from jumping | ||
| 408 | + # extra hoops to detect this possible API misuse. | ||
| 409 | + FontProperties(family="serif-24:style=oblique:weight=bold") | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -574,7 +574,7 @@ def set_useMathText(self, val): | |||
| 574 | 574 | from matplotlib import font_manager | |
| 575 | 575 | ufont = font_manager.findfont( | |
| 576 | 576 | font_manager.FontProperties( | |
| 577 | - mpl.rcParams["font.family"] | ||
| 577 | + family=mpl.rcParams["font.family"] | ||
| 578 | 578 | ), | |
| 579 | 579 | fallback_to_default=False, | |
| 580 | 580 | ) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments