From 3f12eae24d73a93f23d165b383f014545be870f1 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 18 Sep 2018 17:11:43 +0200 Subject: [PATCH] Make arguments to @deprecated/warn_deprecated keyword-only. (except for the deprecated-since version) In 2.2 there were quite a few deprecation warnings of the form ``` warn_deprecated("2.2", "name-of-the-deprecated-API") ``` (e.g. passing 'box-forced' to set_adjustable, or the 'fig' kwarg to get_subplot_params). Such warnings would just display the name of the deprecated API when triggered, without actually including a deprecation message or the deprecated-since version. This is because the correct call would have been ``` warn_deprecated("2.2", name="name-of-the-deprecated-API") ``` (leaving `message` -- the first arg -- to None, and getting an autogenerated message). To avoid this, make all args to `warn_deprecated` and `@deprecated` keyword-only (except the deprecated-since version). There is no deprecation period on the old signature of these deprecator functions(!) because they are clearly intended for internal use, because handling signature changes is a bit of a pain and because deprecations on the deprecation machinery is a bit too meta. --- .../2018-09-18-AL-deprecation-machinery.rst | 8 +++++++ lib/matplotlib/__init__.py | 21 ++++++++++--------- lib/matplotlib/afm.py | 2 +- lib/matplotlib/animation.py | 8 +++---- lib/matplotlib/artist.py | 2 +- lib/matplotlib/axes/_base.py | 7 ++++--- lib/matplotlib/backend_bases.py | 6 +++--- lib/matplotlib/backends/backend_wx.py | 4 ++-- lib/matplotlib/backends/tkagg.py | 3 +-- lib/matplotlib/backends/wx_compat.py | 2 +- lib/matplotlib/cbook/__init__.py | 2 +- lib/matplotlib/cbook/deprecation.py | 10 ++++----- lib/matplotlib/collections.py | 4 ++-- lib/matplotlib/figure.py | 13 ++++++------ lib/matplotlib/markers.py | 12 +++++------ lib/matplotlib/patches.py | 4 ++-- lib/mpl_toolkits/mplot3d/art3d.py | 4 ++-- 17 files changed, 61 insertions(+), 51 deletions(-) create mode 100644 doc/api/next_api_changes/2018-09-18-AL-deprecation-machinery.rst diff --git a/doc/api/next_api_changes/2018-09-18-AL-deprecation-machinery.rst b/doc/api/next_api_changes/2018-09-18-AL-deprecation-machinery.rst new file mode 100644 index 000000000000..78e313ed6bda --- /dev/null +++ b/doc/api/next_api_changes/2018-09-18-AL-deprecation-machinery.rst @@ -0,0 +1,8 @@ +Changes to the signatures of `cbook.deprecated` and `cbook.warn_deprecated` +``````````````````````````````````````````````````````````````````````````` + +All arguments to the `cbook.deprecated` decorator and `cbook.warn_deprecated` +function, except the first one (the version where the deprecation occurred), +are now keyword-only. The goal is to avoid accidentally setting the "message" +argument when the "name" (or "alternative") argument was intended, as this has +repeatedly occurred in the past. diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 7b26604632ea..a294755d9333 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -172,11 +172,11 @@ def compare_versions(a, b): "return True if a is greater than or equal to b" if isinstance(a, bytes): cbook.warn_deprecated( - "3.0", "compare_versions arguments should be strs.") + "3.0", message="compare_versions arguments should be strs.") a = a.decode('ascii') if isinstance(b, bytes): cbook.warn_deprecated( - "3.0", "compare_versions arguments should be strs.") + "3.0", message="compare_versions arguments should be strs.") b = b.decode('ascii') if a: a = distutils.version.LooseVersion(a) @@ -819,7 +819,7 @@ def __setitem__(self, key, val): if key in _deprecated_map: version, alt_key, alt_val, inverse_alt = _deprecated_map[key] cbook.warn_deprecated( - version, key, obj_type="rcparam", alternative=alt_key) + version, name=key, obj_type="rcparam", alternative=alt_key) key = alt_key val = alt_val(val) elif key in _deprecated_remain_as_none and val is not None: @@ -839,8 +839,9 @@ def __setitem__(self, key, val): return elif key == 'examples.directory': cbook.warn_deprecated( - "3.0", "{} is deprecated; in the future, examples will be " - "found relative to the 'datapath' directory.".format(key)) + "3.0", name=key, obj_type="rcparam", addendum="In the " + "future, examples will be found relative to the " + "'datapath' directory.") elif key == 'backend': if val is rcsetup._auto_backend_sentinel: if 'backend' in self: @@ -859,19 +860,19 @@ def __getitem__(self, key): if key in _deprecated_map: version, alt_key, alt_val, inverse_alt = _deprecated_map[key] cbook.warn_deprecated( - version, key, obj_type="rcparam", alternative=alt_key) + version, name=key, obj_type="rcparam", alternative=alt_key) return inverse_alt(dict.__getitem__(self, alt_key)) elif key in _deprecated_ignore_map: version, alt_key = _deprecated_ignore_map[key] cbook.warn_deprecated( - version, key, obj_type="rcparam", alternative=alt_key) + version, name=key, obj_type="rcparam", alternative=alt_key) return dict.__getitem__(self, alt_key) if alt_key else None elif key == 'examples.directory': cbook.warn_deprecated( - "3.0", "{} is deprecated; in the future, examples will be " - "found relative to the 'datapath' directory.".format(key)) + "3.0", name=key, obj_type="rcparam", addendum="In the future, " + "examples will be found relative to the 'datapath' directory.") elif key == "backend": val = dict.__getitem__(self, key) @@ -1019,7 +1020,7 @@ def _rc_params_in_file(fname, fail_on_error=False): elif key in _deprecated_ignore_map: version, alt_key = _deprecated_ignore_map[key] cbook.warn_deprecated( - version, key, alternative=alt_key, + version, name=key, alternative=alt_key, addendum="Please update your matplotlibrc.") else: print(""" diff --git a/lib/matplotlib/afm.py b/lib/matplotlib/afm.py index df8fe8010867..9b93ed540072 100644 --- a/lib/matplotlib/afm.py +++ b/lib/matplotlib/afm.py @@ -357,7 +357,7 @@ def _parse_optional(fh): return d[b'StartKernData'], d[b'StartComposites'] -@deprecated("3.0", "Use the class AFM instead.") +@deprecated("3.0", alternative="the AFM class") def parse_afm(fh): return _parse_afm(fh) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index 1f50f9c7ac11..e27a9a9f9bc9 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -1692,10 +1692,10 @@ def gen(): pass else: cbook.warn_deprecated( - "2.2", "FuncAnimation.save has truncated your " - "animation to 100 frames. In the future, no such " - "truncation will occur; please pass 'save_count' " - "accordingly.") + "2.2", message="FuncAnimation.save has truncated " + "your animation to 100 frames. In the future, no " + "such truncation will occur; please pass " + "'save_count' accordingly.") return gen() diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index c7524c09b528..77c518dc56df 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -533,7 +533,7 @@ def get_picker(self): """ return self._picker - @cbook.deprecated("2.2", "artist.figure is not None") + @cbook.deprecated("2.2", alternative="artist.figure is not None") def is_figure_set(self): """Returns whether the artist is assigned to a `.Figure`.""" return self.figure is not None diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 809342490b84..d28740ff19c3 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -374,8 +374,9 @@ def _plot_args(self, tup, kwargs): ncx, ncy = x.shape[1], y.shape[1] if ncx > 1 and ncy > 1 and ncx != ncy: - cbook.warn_deprecated("2.2", "cycling among columns of inputs " - "with non-matching shapes is deprecated.") + cbook.warn_deprecated( + "2.2", message="cycling among columns of inputs with " + "non-matching shapes is deprecated.") for j in range(max(ncx, ncy)): seg = func(x[:, j % ncx], y[:, j % ncy], kw, kwargs) ret.append(seg) @@ -1653,7 +1654,7 @@ def axis(self, *v, **kwargs): if s == 'normal': cbook.warn_deprecated( "3.1", "Passing 'normal' to axis() is deprecated " - "since %(version)s; use 'auto' instead.") + "since %(since)s; use 'auto' instead.") self.set_autoscale_on(True) self.set_aspect('auto') self.autoscale_view(tight=False) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index a6661ed5b417..0ffee9bb67af 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -1859,9 +1859,9 @@ def enter_notify_event(self, guiEvent=None, xy=None): else: x = None y = None - cbook.warn_deprecated('3.0', 'enter_notify_event expects a ' - 'location but ' - 'your backend did not pass one.') + cbook.warn_deprecated( + '3.0', message='enter_notify_event expects a location but ' + 'your backend did not pass one.') event = LocationEvent('figure_enter_event', self, x, y, guiEvent) self.callbacks.process('figure_enter_event', event) diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index 6f836db94a1f..ee593bdf6ae9 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -123,8 +123,8 @@ class TimerWx(TimerBase): def __init__(self, *args, **kwargs): if args and isinstance(args[0], wx.EvtHandler): cbook.warn_deprecated( - "3.0", "Passing a wx.EvtHandler as first argument to the " - "TimerWx constructor is deprecated since %(version)s.") + "3.0", message="Passing a wx.EvtHandler as first argument to " + "the TimerWx constructor is deprecated since %(since)s.") args = args[1:] TimerBase.__init__(self, *args, **kwargs) self._timer = wx.Timer() diff --git a/lib/matplotlib/backends/tkagg.py b/lib/matplotlib/backends/tkagg.py index 2aa43bf0b3b1..754bfff2f989 100644 --- a/lib/matplotlib/backends/tkagg.py +++ b/lib/matplotlib/backends/tkagg.py @@ -6,8 +6,7 @@ from matplotlib.backends import _tkagg -cbook.warn_deprecated( - "3.0", "The matplotlib.backends.tkagg module is deprecated.") +cbook.warn_deprecated("3.0", name=__name__, obj_type="module") def blit(photoimage, aggimage, bbox=None, colormode=1): diff --git a/lib/matplotlib/backends/wx_compat.py b/lib/matplotlib/backends/wx_compat.py index 78bc34511e3a..0b3d21d56b6b 100644 --- a/lib/matplotlib/backends/wx_compat.py +++ b/lib/matplotlib/backends/wx_compat.py @@ -12,7 +12,7 @@ from .backend_wx import RendererWx -cbook.warn_deprecated("3.0", "{} is deprecated.".format(__name__)) +cbook.warn_deprecated("3.0", name=__name__, obj_type="module") backend_version = wx.VERSION_STRING is_phoenix = 'phoenix' in wx.PlatformInfo diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index 554abe8d6677..cda0836d0c62 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -361,7 +361,7 @@ def file_requires_unicode(x): return False -@deprecated('3.0', 'isinstance(..., numbers.Number)') +@deprecated('3.0', alternative='isinstance(..., numbers.Number)') def is_numlike(obj): """return true if *obj* looks like a number""" return isinstance(obj, (numbers.Number, np.number)) diff --git a/lib/matplotlib/cbook/deprecation.py b/lib/matplotlib/cbook/deprecation.py index 43de50858cd5..69b41e48fe98 100644 --- a/lib/matplotlib/cbook/deprecation.py +++ b/lib/matplotlib/cbook/deprecation.py @@ -25,7 +25,7 @@ def _generate_deprecation_message( obj_type='attribute', addendum='', *, removal=''): if removal == "": - removal = {"2.2": "in 3.1", "3.0": "in 3.2"}.get( + removal = {"2.2": "in 3.1", "3.0": "in 3.2", "3.1": "in 3.3"}.get( since, "two minor releases later") elif removal: if pending: @@ -52,8 +52,8 @@ def _generate_deprecation_message( def warn_deprecated( - since, message='', name='', alternative='', pending=False, - obj_type='attribute', addendum='', *, removal=''): + since, *, message='', name='', alternative='', pending=False, + obj_type='attribute', addendum='', removal=''): """ Used to display deprecation in a standard way. @@ -113,8 +113,8 @@ def warn_deprecated( _warn_external(message, category) -def deprecated(since, message='', name='', alternative='', pending=False, - obj_type=None, addendum='', *, removal=''): +def deprecated(since, *, message='', name='', alternative='', pending=False, + obj_type=None, addendum='', removal=''): """ Decorator to mark a function, a class, or a property as deprecated. diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index e80be08764db..fb15123f586a 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -270,8 +270,8 @@ def draw(self, renderer): except AttributeError: # if we end up with a GC that does not have this method cbook.warn_deprecated( - "3.1", "Your backend does not support setting the hatch " - "color; such backends will become unsupported in " + "3.1", message="Your backend does not support setting the " + "hatch color; such backends will become unsupported in " "Matplotlib 3.3.") if self.get_sketch_params() is not None: diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 819525482cb7..80d204e2b8be 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -89,11 +89,12 @@ def get(self, key): return None cbook.warn_deprecated( "2.1", - "Adding an axes using the same arguments as a previous axes " - "currently reuses the earlier instance. In a future version, " - "a new instance will always be created and returned. Meanwhile, " - "this warning can be suppressed, and the future behavior ensured, " - "by passing a unique label to each axes instance.") + message="Adding an axes using the same arguments as a previous " + "axes currently reuses the earlier instance. In a future " + "version, a new instance will always be created and returned. " + "Meanwhile, this warning can be suppressed, and the future " + "behavior ensured, by passing a unique label to each axes " + "instance.") return item[1] def _entry_from_axes(self, e): @@ -1745,7 +1746,7 @@ def legend(self, *args, **kwargs): if len(extra_args): # cbook.warn_deprecated( # "2.1", - # "Figure.legend will accept no more than two " + # message="Figure.legend will accept no more than two " # "positional arguments in the future. Use " # "'fig.legend(handles, labels, loc=location)' " # "instead.") diff --git a/lib/matplotlib/markers.py b/lib/matplotlib/markers.py index a2088c81de9c..e27e9e6812b6 100644 --- a/lib/matplotlib/markers.py +++ b/lib/matplotlib/markers.py @@ -375,16 +375,16 @@ def _set_tuple_marker(self): self._joinstyle = 'bevel' elif symstyle == 3: cbook.warn_deprecated( - "3.0", "Setting a circle marker using `(..., 3)` is " - "deprecated since Matplotlib 3.0, and support for it will " - "be removed in 3.2. Directly pass 'o' instead.") + "3.0", message="Setting a circle marker using `(..., 3)` " + "is deprecated since Matplotlib 3.0, and support for it " + "will be removed in 3.2. Directly pass 'o' instead.") self._path = Path.unit_circle() self._transform = Affine2D().scale(0.5).rotate_deg(rotation) else: cbook.warn_deprecated( - "3.0", "Passing vertices as `(verts, 0)` is deprecated since " - "Matplotlib 3.0, and support for it will be removed in 3.2. " - "Directly pass `verts` instead.") + "3.0", message="Passing vertices as `(verts, 0)` is " + "deprecated since Matplotlib 3.0, and support for it will be " + "removed in 3.2. Directly pass `verts` instead.") verts = np.asarray(marker[0]) path = Path(verts) self._set_custom_marker(path) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 53590cbd92cf..b7f1a9b41178 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -522,8 +522,8 @@ def _bind_draw_path_function(self, renderer): except AttributeError: # if we end up with a GC that does not have this method cbook.warn_deprecated( - "3.1", "Your backend does not support setting the hatch " - "color; such backends will become unsupported in " + "3.1", message="Your backend does not support setting the " + "hatch color; such backends will become unsupported in " "Matplotlib 3.3.") if self.get_sketch_params() is not None: diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 7777b66c14de..85c4f45cc4d8 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -533,8 +533,8 @@ def set_zsort(self, zsort): """ if zsort is True: cbook.warn_deprecated( - "3.1", "Passing True to mean 'average' for set_zsort is " - "deprecated and support will be removed in Matplotlib 3.3; " + "3.1", message="Passing True to mean 'average' for set_zsort " + "is deprecated and support will be removed in Matplotlib 3.3; " "pass 'average' instead.") zsort = 'average' self._zsortfunc = self._zsort_functions[zsort] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy