Skip to content

Mark artist property aliases explicitly #22749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/devel/documenting_mpl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ gets interpolated into the docstring.
Note that this scheme does not work for decorating an Artist's ``__init__``, as
the subclass and its properties are not defined yet at that point. Instead,
``@_docstring.interpd`` can be used to decorate the class itself -- at that
point, `.kwdoc` can list the properties and interpolate them into
point, `.artist.kwdoc` can list the properties and interpolate them into
``__init__.__doc__``.


Expand Down
14 changes: 13 additions & 1 deletion lib/matplotlib/_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
in your own code. We may change the API at any time with no warning.

"""

from collections import namedtuple
import functools
import itertools
import re
Expand Down Expand Up @@ -58,6 +58,16 @@ def fget(self):
return self._fget


ArtistPropertyInfo = namedtuple('ArtistPropertyInfo', 'kwdoc, is_alias')


def artist_property(kwdoc=None, is_alias=False):
def decorator(func):
func._artist_property = ArtistPropertyInfo(kwdoc, is_alias)
return func
return decorator


# In the following check_foo() functions, the first parameter starts with an
# underscore because it is intended to be positional-only (e.g., so that
# `_api.check_isinstance([...], types=foo)` doesn't fail.
Expand Down Expand Up @@ -261,6 +271,8 @@ def method(self, *args, **kwargs):
method = make_alias(prefix + prop)
method.__name__ = prefix + alias
method.__doc__ = "Alias for `{}`.".format(prefix + prop)
method._artist_property = \
ArtistPropertyInfo(kwdoc=None, is_alias=True)
setattr(cls, prefix + alias, method)
if not exists:
raise ValueError(
Expand Down
7 changes: 6 additions & 1 deletion lib/matplotlib/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,12 @@ def is_alias(self, o):
ds = inspect.getdoc(o)
if ds is None:
return False
return ds.startswith('Alias for ')
result = ds.startswith('Alias for ')
alt_result = (o._artist_property.is_alias
if hasattr(o, '_artist_property')
else False)
assert result == alt_result
return result
Comment on lines +1493 to +1498
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code segment is temporary. I've written it to easily verify that the way of obtaining is_alias via the property is equivalent to getting that information from the docstring. Note that this is already run at import time on all artists via ArtistInspector.__init__ -> ArtistInspector.get_aliases() because we inspect all artists for kwdocs. So if the assert holds in the tests the equivalence is proven.

I propose the following review pattern:

After two people have seen that the tests pass and have approved the PR, I'll change this whole function to only using the new way:

def def is_alias(self, o):
    return (o._artist_property.is_alias
            if hasattr(o, '_artist_property')
            else False)

PLEASE REVIEW, BUT DO NOT MERGE after the second approval.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add that "Alias for..." part of the doc-string based on this? So not only provide an is_alias boolean, but rather a string for which artist property it is an alias for?


def aliased_name(self, s):
"""
Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,7 @@ def get_parse_math(self):
"""Return whether mathtext parsing is considered for this `Text`."""
return self._parse_math

@_api.artist_property(is_alias=True)
def set_fontname(self, fontname):
"""
Alias for `set_family`.
Expand Down