Skip to content

Commit da1ea05

Browse files
authored
Merge pull request matplotlib#17137 from anntzer/pressrelease
Deprecate Toolbar.press/release; add helper to find overridden methods.
2 parents be3e477 + b8eedd8 commit da1ea05

File tree

7 files changed

+82
-30
lines changed

7 files changed

+82
-30
lines changed

doc/api/api_changes_3.3/deprecations.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,14 @@ NavigationToolbar2QT.ctx
377377
~~~~~~~~~~~~~~~~~~~~~~~~
378378
This attribute is deprecated.
379379

380+
NavigationToolbar2.press and .release
381+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382+
These methods were called when pressing or releasing a mouse button,
383+
but *only* when an interactive pan or zoom was occurring (contrary to
384+
what the docs stated). They are deprecated; if you write a backend
385+
which needs to customize such events, please directly override
386+
``press_pan``/``press_zoom``/``release_pan``/``release_zoom`` instead.
387+
380388
Path helpers in :mod:`.bezier`
381389
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382390

lib/matplotlib/axis.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,13 @@ def __init__(self, axes, loc, label=None,
174174
("_get_gridline", "gridline"),
175175
("_get_text1", "label1"),
176176
("_get_text2", "label2")]:
177-
if getattr(self, meth) != getattr(Tick, meth).__get__(self):
178-
cbook.warn_deprecated(
179-
"3.3", message=f"Relying on {meth} to initialize "
180-
f"Tick.{attr} is deprecated since %(since)s and will not "
181-
f"work %(removal)s; please directly set the attribute in "
182-
"the subclass' __init__ instead.")
183-
setattr(self, attr, getattr(self, meth)())
177+
overridden_method = cbook._deprecate_method_override(
178+
getattr(__class__, meth), self, since="3.3", message="Relying "
179+
f"on {meth} to initialize Tick.{attr} is deprecated since "
180+
f"%(since)s and will not work %(removal)s; please directly "
181+
f"set the attribute in the subclass' __init__ instead.")
182+
if overridden_method:
183+
setattr(self, attr, overridden_method())
184184
for artist in [self.tick1line, self.tick2line, self.gridline,
185185
self.label1, self.label2]:
186186
self._set_artist_props(artist)

lib/matplotlib/backend_bases.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2688,14 +2688,6 @@ class NavigationToolbar2:
26882688
:meth:`draw_rubberband` (optional)
26892689
draw the zoom to rect "rubberband" rectangle
26902690
2691-
:meth:`press` (optional)
2692-
whenever a mouse button is pressed, you'll be notified with
2693-
the event
2694-
2695-
:meth:`release` (optional)
2696-
whenever a mouse button is released, you'll be notified with
2697-
the event
2698-
26992691
:meth:`set_message` (optional)
27002692
display message
27012693
@@ -2914,6 +2906,7 @@ def pan(self, *args):
29142906
a.set_navigate_mode(self.mode)
29152907
self.set_message(self.mode)
29162908

2909+
@cbook.deprecated("3.3")
29172910
def press(self, event):
29182911
"""Called whenever a mouse button is pressed."""
29192912

@@ -2937,7 +2930,12 @@ def press_pan(self, event):
29372930
self.canvas.mpl_disconnect(self._id_drag)
29382931
self._id_drag = self.canvas.mpl_connect(
29392932
'motion_notify_event', self.drag_pan)
2940-
self.press(event)
2933+
press = cbook._deprecate_method_override(
2934+
__class__.press, self, since="3.3", message="Calling an "
2935+
"overridden press() at pan start is deprecated since %(since)s "
2936+
"and will be removed %(removal)s; override press_pan() instead.")
2937+
if press is not None:
2938+
press(event)
29412939

29422940
def press_zoom(self, event):
29432941
"""Callback for mouse button press in zoom to rect mode."""
@@ -2959,7 +2957,12 @@ def press_zoom(self, event):
29592957
"axes": axes,
29602958
"cid": id_zoom,
29612959
}
2962-
self.press(event)
2960+
press = cbook._deprecate_method_override(
2961+
__class__.press, self, since="3.3", message="Calling an "
2962+
"overridden press() at zoom start is deprecated since %(since)s "
2963+
"and will be removed %(removal)s; override press_zoom() instead.")
2964+
if press is not None:
2965+
press(event)
29632966

29642967
def push_current(self):
29652968
"""Push the current view limits and position onto the stack."""
@@ -2972,6 +2975,7 @@ def push_current(self):
29722975
for ax in self.canvas.figure.axes}))
29732976
self.set_history_buttons()
29742977

2978+
@cbook.deprecated("3.3")
29752979
def release(self, event):
29762980
"""Callback for mouse button release."""
29772981

@@ -2990,7 +2994,12 @@ def release_pan(self, event):
29902994
self._xypress = []
29912995
self._button_pressed = None
29922996
self.push_current()
2993-
self.release(event)
2997+
release = cbook._deprecate_method_override(
2998+
__class__.press, self, since="3.3", message="Calling an "
2999+
"overridden release() at pan stop is deprecated since %(since)s "
3000+
"and will be removed %(removal)s; override release_pan() instead.")
3001+
if release is not None:
3002+
release(event)
29943003
self._draw()
29953004

29963005
def drag_pan(self, event):
@@ -3033,7 +3042,13 @@ def release_zoom(self, event):
30333042
if ((abs(x - start_x) < 5 and event.key != "y") or
30343043
(abs(y - start_y) < 5 and event.key != "x")):
30353044
self._xypress = None
3036-
self.release(event)
3045+
release = cbook._deprecate_method_override(
3046+
__class__.press, self, since="3.3", message="Calling an "
3047+
"overridden release() at zoom stop is deprecated since "
3048+
"%(since)s and will be removed %(removal)s; override "
3049+
"release_zoom() instead.")
3050+
if release is not None:
3051+
release(event)
30373052
self._draw()
30383053
return
30393054

@@ -3052,7 +3067,13 @@ def release_zoom(self, event):
30523067
self._zoom_info = None
30533068

30543069
self.push_current()
3055-
self.release(event)
3070+
release = cbook._deprecate_method_override(
3071+
__class__.press, self, since="3.3", message="Calling an "
3072+
"overridden release() at zoom stop is deprecated since %(since)s "
3073+
"and will be removed %(removal)s; override release_zoom() "
3074+
"instead.")
3075+
if release is not None:
3076+
release(event)
30563077

30573078
@cbook.deprecated("3.3", alternative="toolbar.canvas.draw_idle()")
30583079
def draw(self):

lib/matplotlib/backends/backend_wx.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,8 @@ def set_cursor(self, cursor):
12021202
self.canvas.SetCursor(cursor)
12031203
self.canvas.Update()
12041204

1205-
def press(self, event):
1205+
def press_zoom(self, event):
1206+
super().press_zoom(event)
12061207
if self.mode.name == 'ZOOM':
12071208
if not self.retinaFix:
12081209
self.wxoverlay = wx.Overlay()
@@ -1214,7 +1215,8 @@ def press(self, event):
12141215
self.zoomStartY = event.ydata
12151216
self.zoomAxes = event.inaxes
12161217

1217-
def release(self, event):
1218+
def release_zoom(self, event):
1219+
super().release_zoom(event)
12181220
if self.mode.name == 'ZOOM':
12191221
# When the mouse is released we reset the overlay and it
12201222
# restores the former content to the window.

lib/matplotlib/cbook/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from .deprecation import (
3232
deprecated, warn_deprecated,
3333
_rename_parameter, _delete_parameter, _make_keyword_only,
34+
_deprecate_method_override,
3435
_suppress_matplotlib_deprecation_warning,
3536
MatplotlibDeprecationWarning, mplDeprecation)
3637

lib/matplotlib/cbook/deprecation.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,31 @@ def wrapper(*args, **kwargs):
429429
return wrapper
430430

431431

432+
def _deprecate_method_override(method, obj, **kwargs):
433+
"""
434+
Return ``obj.method`` with a deprecation if it was overridden, else None.
435+
436+
Parameters
437+
----------
438+
method
439+
An unbound method, i.e. an expression of the form
440+
``Class.method_name``. Remember that within the body of a method, one
441+
can always use ``__class__`` to refer to the class that is currently
442+
being defined.
443+
obj
444+
An object of the class where *method* is defined.
445+
**kwargs
446+
Additional parameters passed to `warn_deprecated` to generate the
447+
deprecation warning; must at least include the "since" key.
448+
"""
449+
name = method.__name__
450+
bound_method = getattr(obj, name)
451+
if bound_method != method.__get__(obj):
452+
warn_deprecated(**{"name": name, "obj_type": "method", **kwargs})
453+
return bound_method
454+
return None
455+
456+
432457
@contextlib.contextmanager
433458
def _suppress_matplotlib_deprecation_warning():
434459
with warnings.catch_warnings():

lib/matplotlib/offsetbox.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,15 +1700,10 @@ def __init__(self, ref_artist, use_blit=False):
17001700

17011701
if not ref_artist.pickable():
17021702
ref_artist.set_picker(True)
1703-
with cbook._suppress_matplotlib_deprecation_warning():
1704-
if self.artist_picker != DraggableBase.artist_picker.__get__(self):
1705-
overridden_picker = self.artist_picker
1706-
else:
1707-
overridden_picker = None
1703+
overridden_picker = cbook._deprecate_method_override(
1704+
__class__.artist_picker, self, since="3.3",
1705+
addendum="Directly set the artist's picker if desired.")
17081706
if overridden_picker is not None:
1709-
cbook.warn_deprecated(
1710-
"3.3", name="artist_picker", obj_type="method",
1711-
addendum="Directly set the artist's picker if desired.")
17121707
ref_artist.set_picker(overridden_picker)
17131708
self.cids = [c2, c3]
17141709

0 commit comments

Comments
 (0)