From 0316ae1199e5b62ed2fdf229fd3491c4cf60c531 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sun, 9 Dec 2018 21:31:08 +0100 Subject: [PATCH] Deprecate setting the same property under two different aliases. This will allow getting rid of the notion of alias priority, and is consistent with Python's behavior (as explained in the changelog entry). --- doc/api/next_api_changes/2018-12-09-AL.rst | 19 +++++++++++++++++++ lib/matplotlib/artist.py | 6 +++--- lib/matplotlib/cbook/__init__.py | 8 +++++--- 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 doc/api/next_api_changes/2018-12-09-AL.rst diff --git a/doc/api/next_api_changes/2018-12-09-AL.rst b/doc/api/next_api_changes/2018-12-09-AL.rst new file mode 100644 index 000000000000..1cebeca5f822 --- /dev/null +++ b/doc/api/next_api_changes/2018-12-09-AL.rst @@ -0,0 +1,19 @@ +Setting the same artist property multiple time via aliases is deprecated +```````````````````````````````````````````````````````````````````````` + +Previously, code such as ``plt.plot([0, 1], c="red", color="blue")`` would +emit a warning indicating that ``c`` and ``color`` are aliases of one another, +and only keep the ``color`` kwarg. This behavior is deprecated; in a future +version, this will raise a TypeError, similarly to Python's behavior when a +keyword argument is passed twice (``plt.plot([0, 1], c="red", c="blue")``). + +This warning is raised by `~.cbook.normalize_kwargs`. + +Artist.set now normalizes keywords before sorting them +`````````````````````````````````````````````````````` + +`Artist.set` currently sorts its keyword arguments in reverse alphabetical +order (with a special-case to put ``color`` at the end) before applying them. + +It now normalizes aliases (and, as above, emits a warning on duplicate +properties) before doing the sorting (so ``c`` goes to the end too). diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index b1c19cfceabe..31cc84cccfa4 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -1063,12 +1063,12 @@ def properties(self): return ArtistInspector(self).properties() def set(self, **kwargs): - """A property batch setter. Pass *kwargs* to set properties. - """ + """A property batch setter. Pass *kwargs* to set properties.""" + kwargs = cbook.normalize_kwargs( + kwargs, getattr(type(self), "_alias_map", {})) props = OrderedDict( sorted(kwargs.items(), reverse=True, key=lambda x: (self._prop_order.get(x[0], 0), x[0]))) - return self.update(props) def findobj(self, match=None, include_self=True): diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index f8eede700035..328cf6d8739d 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -1725,9 +1725,11 @@ def normalize_kwargs(kw, alias_mapping=None, required=(), forbidden=(), if tmp: ret[canonical] = tmp[-1] if len(tmp) > 1: - _warn_external("Saw kwargs {seen!r} which are all aliases for " - "{canon!r}. Kept value from {used!r}".format( - seen=seen, canon=canonical, used=seen[-1])) + warn_deprecated( + "3.1", message=f"Saw kwargs {seen!r} which are all " + f"aliases for {canonical!r}. Kept value from " + f"{seen[-1]!r}. Passing multiple aliases for the same " + f"property will raise a TypeError %(removal)s.") # at this point we know that all keys which are aliased are removed, update # the return dictionary from the cleaned local copy of the input