8000 Clarify error message for bad keyword arguments. by anntzer · Pull Request #22451 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Clarify error message for bad keyword arguments. #22451

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
Feb 15, 2022
Merged
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
76 changes: 48 additions & 28 deletions lib/matplotlib/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,32 +1048,6 @@ def set_in_layout(self, in_layout):
"""
self._in_layout = in_layout

def update(self, props):
"""
Update this artist's properties from the dict *props*.

Parameters
----------
props : dict
"""
ret = []
with cbook._setattr_cm(self, eventson=False):
for k, v in props.items():
# Allow attributes we want to be able to update through
# art.update, art.set, setp.
if k == "axes":
ret.append(setattr(self, k, v))
else:
func = getattr(self, f"set_{k}", None)
if not callable(func):
raise AttributeError(f"{type(self).__name__!r} object "
f"has no property {k!r}")
ret.append(func(v))
if ret:
self.pchanged()
self.stale = True
return ret

def get_label(self):
"""Return the label used for this artist in the legend."""
return self._label
Expand Down Expand Up @@ -1161,12 +1135,58 @@ def properties(self):
"""Return a dictionary of all the properties of the artist."""
return ArtistInspector(self).properties()

def _update_props(self, props, errfmt):
"""
Helper for `.Artist.set` and `.Artist.update`.

*errfmt* is used to generate error messages for invalid property
names; it get formatted with ``type(self)`` and the property name.
"""
ret = []
with cbook._setattr_cm(self, eventson=False):
for k, v in props.items():
# Allow attributes we want to be able to update through
# art.update, art.set, setp.
if k == "axes":
ret.append(setattr(self, k, v))
else:
func = getattr(self, f"set_{k}", None)
if not callable(func):
raise AttributeError(
errfmt.format(cls=type(self), prop_name=k))
ret.append(func(v))
if ret:
self.pchanged()
self.stale = True
return ret

def update(self, props):
"""
Update this artist's properties from the dict *props*.

Parameters
----------
props : dict
"""
return self._update_props(
props, "{cls.__name__!r} object has no property {prop_name!r}")

def _internal_update(self, kwargs):
"""
Update artist properties without prenormalizing them, but generating
errors as if calling `set`.

The lack of prenormalization is to maintain backcompatibility.
"""
return self._update_props(
kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
"{prop_name!r}")

def set(self, **kwargs):
# docstring and signature are auto-generated via
# Artist._update_set_signature_and_docstring() at the end of the
# module.
kwargs = cbook.normalize_kwargs(kwargs, self)
return self.update(kwargs)
return self._internal_update(cbook.normalize_kwargs(kwargs, self))

@contextlib.contextmanager
def _cm_set(self, **kwargs):
Expand Down
20 changes: 10 additions & 10 deletions lib/matplotlib/axes/_axes.py
< EDBE td class="blob-code blob-code-context js-file-line"> collection.set_norm(norm)
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def set_title(self, label, fontdict=None, loc=None, pad=None, *, y=None,
title.update(default)
if fontdict is not None:
title.update(fontdict)
title.update(kwargs)
title._internal_update(kwargs)
return title

def get_legend_handles_labels(self, legend_handler_map=None):
Expand Down Expand Up @@ -1064,7 +1064,7 @@ def hlines(self, y, xmin, xmax, colors=None, linestyles='solid',
lines = mcoll.LineCollection(masked_verts, colors=colors,
linestyles=linestyles, label=label)
self.add_collection(lines, autolim=False)
lines.update(kwargs)
lines._internal_update(kwargs)

if len(y) > 0:
minx = min(xmin.min(), xmax.min())
Expand Down Expand Up @@ -1143,7 +1143,7 @@ def vlines(self, x, ymin, ymax, colors=None, linestyles='solid',
lines = mcoll.LineCollection(masked_verts, colors=colors,
linestyles=linestyles, label=label)
self.add_collection(lines, autolim=False)
lines.update(kwargs)
lines._internal_update(kwargs)

if len(x) > 0:
minx = x.min()
Expand Down Expand Up @@ -1363,7 +1363,7 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
color=color,
linestyle=linestyle)
self.add_collection(coll, autolim=False)
coll.update(kwargs)
coll._internal_update(kwargs)
colls.append(coll)

if len(positions) > 0:
Expand Down Expand Up @@ -2410,7 +2410,7 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
label='_nolegend_',
hatch=htch,
)
r.update(kwargs)
r._internal_update(kwargs)
r.get_path()._interpolation_steps = 100
if orientation == 'vertical':
r.sticky_edges.y.append(b)
Expand Down Expand Up @@ -4502,7 +4502,7 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
collection.set_cmap(cmap)
collection._scale_norm(norm, vmin, vmax)
collection.update(kwargs)
collection._internal_update(kwargs)

# Classic mode only:
# ensure there are margins to allow for the
Expand Down Expand Up @@ -4830,7 +4830,7 @@ def reduce_C_function(C: array) -> float
collection.set_cmap(cmap)
collection.set_norm(norm)
collection.set_alpha(alpha)
collection.update(kwargs)
collection._internal_update(kwargs)
collection._scale_norm(norm, vmin, vmax)

corners = ((xmin, ymin), (xmax, ymax))
Expand Down Expand Up @@ -4882,7 +4882,7 @@ def reduce_C_function(C: array) -> float
bar.set_cmap(cmap)
bar.set_norm(norm)
bar.set_alpha(alpha)
bar.update(kwargs)
bar._internal_update(kwargs)
bars.append(self.add_collection(bar, autolim=False))

collection.hbar, collection.vbar = bars
Expand Down Expand Up @@ -6763,11 +6763,11 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
for patch, lbl in itertools.zip_longest(patches, labels):
if patch:
p = patch[0]
p.update(kwargs)
p._internal_update(kwargs)
if lbl is not None:
p.set_label(lbl)
for p in patch[1:]:
p.update(kwargs)
p._internal_update(kwargs)
p.set_label('_nolegend_')

if nx == 1:
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ def __init__(self, fig, rect,
if yscale:
self.set_yscale(yscale)

self.update(kwargs)
self._internal_update(kwargs)

for name, axis in self._get_axis_map().items():
axis.callbacks._pickled_cids.add(
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1818,10 +1818,10 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs):
tick_label = formatter(loc, pos)
# deal with label1
tick.label1.set_text(tick_label)
tick.label1.update(kwargs)
tick.label1._internal_update(kwargs)
# deal with label2
tick.label2.set_text(tick_label)
tick.label2.update(kwargs)
tick.label2._internal_update(kwargs)
# only return visible tick labels
if tick.label1.get_visible():
ret.append(tick.label1)
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def __init__(self,
self._offset_transform = offset_transform

self._path_effects = None
self.update(kwargs)
self._internal_update(kwargs)
self._paths = None

def get_paths(self):
Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def __init__(self, ax,

self._imcache = None

self.update(kwargs)
self._internal_update(kwargs)

def __getstate__(self):
# Save some space on the pickle by not saving the cache.
Expand Down Expand Up @@ -1215,7 +1215,7 @@ def __init__(self, ax,
**kwargs : `.Artist` properties
"""
super().__init__(ax, norm=norm, cmap=cmap)
self.update(kwargs)
self._internal_update(kwargs)
if A is not None:
self.set_data(x, y, A)

Expand Down Expand Up @@ -1356,7 +1356,7 @@ def __init__(self, fig,
self.figure = fig
self.ox = offsetx
self.oy = offsety
self.update(kwargs)
self._internal_update(kwargs)
self.magnification = 1.0

def get_extent(self):
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ def __init__(self, xdata, ydata,

# update kwargs before updating data to give the caller a
# chance to init axes (and hence unit support)
self.update(kwargs)
self._internal_update(kwargs)
self.pickradius = pickradius
self.ind_offset = 0
if (isinstance(self._picker, Number) and
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/offsetbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class OffsetBox(martist.Artist):
"""
def __init__(self, *args, **kwargs):
super().__init__(*args)
self.update(kwargs)
self._internal_update(kwargs)
# Clipping has not been implemented in the OffsetBox family, so
# disable the clip flag for consistency. It can always be turned back
# on to zero effect.
Expand Down Expand Up @@ -1359,7 +1359,7 @@ def __init__(self, offsetbox, xy,
if bboxprops:
self.patch.set(**bboxprops)

self.update(kwargs)
self._internal_update(kwargs)

@property
def xyann(self):
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def __init__(self,
self.set_joinstyle(joinstyle)

if len(kwargs):
self.update(kwargs)
self._internal_update(kwargs)

def get_verts(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/projections/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ def set_thetagrids(self, angles, labels=None, fmt=None, **kwargs):
elif fmt is not None:
self.xaxis.set_major_formatter(mticker.FormatStrFormatter(fmt))
for t in self.xaxis.get_ticklabels():
t.update(kwargs)
t._internal_update(kwargs)
return self.xaxis.get_ticklines(), self.xaxis.get_ticklabels()

def set_rgrids(self, radii, labels=None, angle=None, fmt=None, **kwargs):
Expand Down Expand Up @@ -1362,7 +1362,7 @@ def set_rgrids(self, radii, labels=None, angle=None, fmt=None, **kwargs):
angle = self.get_rlabel_position()
self.set_rlabel_position(angle)
for t in self.yaxis.get_ticklabels():
t.update(kwargs)
t._internal_update(kwargs)
return self.yaxis.get_gridlines(), self.yaxis.get_ticklabels()

def format_coord(self, theta, r):
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/pyplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ def xticks(ticks=None, labels=None, **kwargs):
if labels is None:
labels = ax.get_xticklabels()
for l in labels:
l.update(kwargs)
l._internal_update(kwargs)
else:
labels = ax.set_xticklabels(labels, **kwargs)

Expand Down Expand Up @@ -1849,7 +1849,7 @@ def yticks(ticks=None, labels=None, **kwargs):
if labels is None:
labels = ax.get_yticklabels()
for l in labels:
l.update(kwargs)
l._internal_update(kwargs)
else:
labels = ax.set_yticklabels(labels, **kwargs)

Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def set_text_props(self, **kwargs):

%(Text:kwdoc)s
"""
self._text.update(kwargs)
self._text._internal_update(kwargs)
self.stale = True

@property
Expand Down Expand Up @@ -315,7 +315,7 @@ def __init__(self, ax, loc=None, bbox=None, **kwargs):
self._edges = None
self._autoColumns = []
self._autoFontsize = True
self.update(kwargs)
self._internal_update(kwargs)

self.set_clip_on(False)

Expand Down
0