8000 Modernize ArtistInspector a bit... by anntzer · Pull Request #12038 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Modernize ArtistInspector a bit... #12038

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

Merged
merged 1 commit into from
Sep 7, 2018
Merged
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
117 changes: 34 additions & 83 deletions lib/matplotlib/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,6 @@
from .path import Path
from .transforms import (Bbox, IdentityTransform, Transform, TransformedBbox,
TransformedPatchPath, TransformedPath)
# Note, matplotlib artists use the doc strings for set and get
Copy link
Contributor Author

Choose a reason for hiding this comment

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

that comment is essentially completely false now (even the magic string for aliases is "Alias for", not "alias for" :))

# methods to enable the introspection methods of setp and getp. Every
# set_* method should have a docstring containing the line
#
# ACCEPTS: [ legal | values ]
#
# and aliases for setters and getters should have a docstring that
# starts with 'alias for ', as in 'alias for set_somemethod'
#
# You may wonder why we use so much boiler-plate manually defining the
# set_alias and get_alias functions, rather than using some clever
# python trick. The answer is that I need to be able to manipulate
# the docstring, and there is no clever way to do that in python 2.2,
# as far as I can see - see
#
# https://mail.python.org/pipermail/python-list/2004-October/242925.html


def allow_rasterization(draw):
Expand Down Expand Up @@ -1181,7 +1165,7 @@ def __init__(self, o):
o = o[0]

self.oorig = o
if not inspect.isclass(o):
if not isinstance(o, type):
o = type(o)
self.o = o

Expand Down Expand Up @@ -1220,12 +1204,9 @@ def get_valid_values(self, attr):
"""
Get the legal arguments for the setter associated with *attr*.

This is done by querying the docstring of the function *set_attr*
for a line that begins with "ACCEPTS" or ".. ACCEPTS":

e.g., for a line linestyle, return
"[ ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'steps'`` | ``'None'``
]"
This is done by querying the docstring of the setter for a line that
begins with "ACCEPTS:" or ".. ACCEPTS:", and then by looking for a
numpydoc-style documentation for the setter's first argument.
"""

name = 'set_%s' % attr
Expand Down Expand Up @@ -1258,7 +1239,6 @@ def _get_setters_and_targets(self):
Get the attribute strings and a full path to where the setter
is defined for all setters in an object.
"""

setters = []
for name in dir(self.o):
if not name.startswith('set_'):
Expand All @@ -1283,10 +1263,8 @@ def _replace_path(self, source_class):
Changes the full path to the public API path that is used
in sphinx. This is needed for links to work.
"""

replace_dict = {'_base._AxesBase': 'Axes',
'_axes.Axes': 'Axes'}

'_axes.Axes': 'Axes'}
for key, value in replace_dict.items():
source_class = source_class.replace(key, value)
return source_class
Expand All @@ -1296,50 +1274,36 @@ def get_setters(self):
Get the attribute strings with setters for object. e.g., for a line,
return ``['markerfacecolor', 'linewidth', ....]``.
"""

return [prop for prop, target in self._get_setters_and_targets()]

def is_alias(self, o):
"""
Return *True* if method object *o* is an alias for another
function.
"""
"""Return whether method object *o* is an alias for another method."""
ds = o.__doc__
if ds is None:
return False
return ds.startswith('Alias for ')

def aliased_name(self, s):
"""
return 'PROPNAME or alias' if *s* has an alias, else return
PROPNAME.
Return 'PROPNAME or alias' if *s* has an alias, else return 'PROPNAME'.

e.g., for the line markerfacecolor property, which has an
alias, return 'markerfacecolor or mfc' and for the transform
property, which does not, return 'transform'
property, which does not, return 'transform'.
"""

if s in self.aliasd:
return s + ''.join([' or %s' % x
for x in sorted(self.aliasd[s])])
else:
return s
aliases = ''.join(' or %s' % x for x in sorted(self.aliasd.get(s, [])))
return s + aliases

def aliased_name_rest(self, s, target):
"""
return 'PROPNAME or alias' if *s* has an alias, else return
PROPNAME formatted for ReST
Return 'PROPNAME or alias' if *s* has an alias, else return 'PROPNAME',
formatted for ReST.

e.g., for the line markerfacecolor property, which has an
alias, return 'markerfacecolor or mfc' and for the transform
property, which does not, return 'transform'
property, which does not, return 'transform'.
"""

if s in self.aliasd:
aliases = ''.join([' or %s' % x
for x in sorted(self.aliasd[s])])
else:
aliases = ''
aliases = ''.join(' or %s' % x for x in sorted(self.aliasd.get(s, [])))
return ':meth:`%s <%s>`%s' % (s, target, aliases)

def pprint_setters(self, prop=None, leadingspace=2):
Expand Down Expand Up @@ -1387,52 +1351,43 @@ def pprint_setters_rest(self, prop=None, leadingspace=4):
accepts = self.get_valid_values(prop)
return '%s%s: %s' % (pad, prop, accepts)

attrs = self._get_setters_and_targets()
attrs.sort()
attrs = sorted(self._get_setters_and_targets())
lines = []

########
names = [self.aliased_name_rest(prop, target)
for prop, target in attrs]
accepts = [self.get_valid_values(prop) for prop, target in attrs]

col0_len = max(len(n) for n in names)
col1_len = max(len(a) for a in accepts)

lines.append('')
lines.append(pad + '.. table::')
lines.append(pad + ' :class: property-table')
pad += ' '

table_formatstr = pad + '=' * col0_len + ' ' + '=' * col1_len

lines.append('')
lines.append(table_formatstr)
lines.append(pad + 'Property'.ljust(col0_len + 3) +
'Description'.ljust(col1_len))
lines.append(table_formatstr)

lines.extend([pad + n.ljust(col0_len + 3) + a.ljust(col1_len)
for n, a in zip(names, accepts)])

lines.append(table_formatstr)
lines.append('')
return lines
table_formatstr = pad + ' ' + '=' * col0_len + ' ' + '=' * col1_len

return [
'',
pad + '.. table::',
pad + ' :class: property-table',
'',
table_formatstr,
pad + ' ' + 'Property'.ljust(col0_len)
+ ' ' + 'Description'.ljust(col1_len),
table_formatstr,
*[pad + ' ' + n.ljust(col0_len) + ' ' + a.ljust(col1_len)
for n, a in zip(names, accepts)],
table_formatstr,
'',
]

def properties(self):
"""
return a dictionary mapping property name -> value
"""
"""Return a dictionary mapping property name -> value."""
o = self.oorig
getters = [name for name in dir(o)
if name.startswith('get_') and callable(getattr(o, name))]
getters.sort()
d = dict()
d = {}
for name in getters:
func = getattr(o, name)
if self.is_alias(func):
continue

try:
with warnings.catch_warnings():
warnings.simplefilter('ignore')
Expand All @@ -1441,14 +1396,10 @@ def properties(self):
continue
else:
d[name[4:]] = val

return d

def pprint_getters(self):
"""
Return the getters and actual values as list of strings.
"""

"""Return the getters and actual values as list of strings."""
lines = []
for name, val in sorted(self.properties().items()):
if getattr(val, 'shape', ()) != () and len(val) > 6:
Expand Down
0