Skip to content

Commit 4f8343b

Browse files
committed
MNT: unify code path of set, update, setp
Single code path for the property -> setter lookup logic.
1 parent 00b74bd commit 4f8343b

File tree

2 files changed

+55
-40
lines changed

2 files changed

+55
-40
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
`Artist.update` has return value
2+
````````````````````````````````
3+
4+
The methods `matplotlib.artist.Artist.set`,
5+
`matplotlib.Artist.update`, and the function `matplotlib.artist.setp`
6+
now use a common codepath to loop up how to update the given artist
7+
properties (either using the setter methods or an attribute/property).
8+
9+
The behavior of `matplotlib.Artist.update` is slightly changed to now
10+
sort by key name and returns a list of the returned values from the
11+
setter methods to avoid changing the API of
12+
`matplotlib.Artist.set` and `matplotlib.artist.setp`.

lib/matplotlib/artist.py

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -845,21 +845,46 @@ def update(self, props):
845845
"""
846846
store = self.eventson
847847
self.eventson = False
848-
changed = False
848+
try:
849+
ret = [self._update_property(k, v)
850+
for k, v in sorted(props.items(), reverse=True)]
851+
finally:
852+
self.eventson = store
849853

850-
for k, v in six.iteritems(props):
851-
if k in ['axes']:
852-
setattr(self, k, v)
853-
else:
854-
func = getattr(self, 'set_' + k, None)
855-
if func is None or not six.callable(func):
856-
raise AttributeError('Unknown property %s' % k)
857-
func(v)
858-
changed = True
859-
self.eventson = store
860-
if changed:
854+
if len(ret):
861855
self.pchanged()
862856
self.stale = True
857+
return ret
858+
859+
def _update_property(self, k, v):
860+
"""helper function for set, update, setp
861+
862+
This function takes care of sorting out if this should be done
863+
through a `set_*` method or a property.
864+
865+
Parameters
866+
----------
867+
k : str
868+
The property to update
869+
870+
v : obj
871+
The value to assign to the property
872+
873+
Returns
874+
-------
875+
ret : obj or None
876+
If using a `set_*` method return it's return, else return None.
877+
"""
878+
k = k.lower()
879+
# white list attributes we want to be able to update through
880+
# art.update, art.set, setp
881+
if k in ['axes']:
882+
return setattr(self, k, v)
883+
else:
884+
func = getattr(self, 'set_' + k, None)
885+
if func is None or not six.callable(func):
886+
raise AttributeError('Unknown property %s' % k)
887+
return func(v)
863888

864889
def get_label(self):
865890
"""
@@ -919,23 +944,9 @@ def properties(self):
919944
return ArtistInspector(self).properties()
920945

921946
def set(self, **kwargs):
947+
"""A property batch setter. Pass *kwargs* to set properties.
922948
"""
923-
A property batch setter. Pass *kwargs* to set properties.
924-
Will handle property name collisions (e.g., if both
925-
'color' and 'facecolor' are specified, the property
926-
with higher priority gets set last).
927-
928-
"""
929-
ret = []
930-
for k, v in sorted(kwargs.items(), reverse=True):
931-
k = k.lower()
932-
funcName = "set_%s" % k
933-
func = getattr(self, funcName, None)
934-
if func is None:
935-
raise TypeError('There is no %s property "%s"' %
936-
(self.__class__.__name__, k))
937-
ret.extend([func(v)])
938-
return ret
949+
return self.update(kwargs)
939950

940951
def findobj(self, match=None, include_self=True):
941952
"""
@@ -1453,18 +1464,10 @@ def setp(obj, *args, **kwargs):
14531464
funcvals = []
14541465
for i in range(0, len(args) - 1, 2):
14551466
funcvals.append((args[i], args[i + 1]))
1456-
funcvals.extend(sorted(kwargs.items(), reverse=True))
1457-
1458-
ret = []
1459-
for o in objs:
1460-
for s, val in funcvals:
1461-
s = s.lower()
1462-
funcName = "set_%s" % s
1463-
func = getattr(o, funcName, None)
1464-
if func is None:
1465-
raise TypeError('There is no %s property "%s"' %
1466-
(o.__class__.__name__, s))
1467-
ret.extend([func(val)])
1467+
# do the *args one at a time to ensure order
1468+
ret = [o.update({s: val}) for s, val in funcvals for o in objs]
1469+
# apply kwargs in bulk
1470+
ret.extend([o.update(kwargs) for o in objs])
14681471
return [x for x in cbook.flatten(ret)]
14691472

14701473

0 commit comments

Comments
 (0)