Skip to content

Commit 71338e3

Browse files
authored
Merge pull request #12170 from anntzer/Timer.remove_callback
API: Deprecate considering *args, **kwargs in Timer.remove_callback.
2 parents 0f31612 + 55897f7 commit 71338e3

File tree

2 files changed

+58
-20
lines changed

2 files changed

+58
-20
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Timer.remove_callback won't consider ``*args, **kwargs`` in a future version
2+
````````````````````````````````````````````````````````````````````````````
3+
4+
Currently, ``Timer.remove_callback(func, *args, **kwargs)`` removes a callback
5+
previously added by ``Timer.add_callback(func, *args, **kwargs)``, but if
6+
``*args, **kwargs`` is not passed in (``Timer.remove_callback(func)``), then
7+
the first callback with a matching ``func`` is removed, regardless of whether
8+
it was added with or without ``*args, **kwargs``.
9+
10+
In a future version, ``Timer.remove_callback`` will always use the latter
11+
behavior (not consider ``*args, **kwargs``); to specifically consider them, add
12+
the callback as a `functools.partial` object ::
13+
14+
cb = timer.add_callback(functools.partial(func, *args, **kwargs))
15+
# ...
16+
# later
17+
timer.remove_callback(cb)
18+
19+
``Timer.add_callback`` was modified to return *func* to simplify the above
20+
usage (previously it returned None); this also allows using it as a decorator.
21+
22+
The new API is modelled after `atexit.register` / `atexit.unregister`.

lib/matplotlib/backend_bases.py

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,7 @@ def set_sketch_params(self, scale=None, length=None, randomness=None):
10391039

10401040

10411041
class TimerBase(object):
1042-
'''
1042+
"""
10431043
A base class for providing timer events, useful for things animations.
10441044
Backends need to implement a few specific methods in order to use their
10451045
own timing mechanisms so that the timer events are integrated into their
@@ -1082,8 +1082,7 @@ class TimerBase(object):
10821082
Stores list of (func, args, kwargs) tuples that will be called upon
10831083
timer events. This list can be manipulated directly, or the
10841084
functions `add_callback` and `remove_callback` can be used.
1085-
1086-
'''
1085+
"""
10871086
def __init__(self, interval=None, callbacks=None):
10881087
#Initialize empty callbacks list and setup default settings if necssary
10891088
if callbacks is None:
@@ -1102,22 +1101,25 @@ def __init__(self, interval=None, callbacks=None):
11021101
self._timer = None
11031102

11041103
def __del__(self):
1105-
'Need to stop timer and possibly disconnect timer.'
1104+
"""Need to stop timer and possibly disconnect timer."""
11061105
self._timer_stop()
11071106

11081107
def start(self, interval=None):
1109-
'''
1110-
Start the timer object. `interval` is optional and will be used
1111-
to reset the timer interval first if provided.
1112-
'''
1108+
"""
1109+
Start the timer object.
1110+
1111+
Parameters
1112+
----------
1113+
interval : int, optional
1114+
Timer interval in milliseconds; overrides a previously set interval
1115+
if provided.
1116+
"""
11131117
if interval is not None:
11141118
self._set_interval(interval)
11151119
self._timer_start()
11161120

11171121
def stop(self):
1118-
'''
1119-
Stop the timer.
1120-
'''
1122+
"""Stop the timer."""
11211123
self._timer_stop()
11221124

11231125
def _timer_start(self):
@@ -1148,19 +1150,33 @@ def single_shot(self, ss):
11481150
self._timer_set_single_shot()
11491151

11501152
def add_callback(self, func, *args, **kwargs):
1151-
'''
1153+
"""
11521154
Register *func* to be called by timer when the event fires. Any
11531155
additional arguments provided will be passed to *func*.
1154-
'''
1156+
1157+
This function returns *func*, which makes it possible to use it as a
1158+
decorator.
1159+
"""
11551160
self.callbacks.append((func, args, kwargs))
1161+
return func
11561162

11571163
def remove_callback(self, func, *args, **kwargs):
1158-
'''
1159-
Remove *func* from list of callbacks. *args* and *kwargs* are optional
1160-
and used to distinguish between copies of the same function registered
1161-
to be called with different arguments.
1162-
'''
1164+
"""
1165+
Remove *func* from list of callbacks.
1166+
1167+
*args* and *kwargs* are optional and used to distinguish between copies
1168+
of the same function registered to be called with different arguments.
1169+
This behavior is deprecated. In the future, `*args, **kwargs` won't be
1170+
considered anymore; to keep a specific callback removable by itself,
1171+
pass it to `add_callback` as a `functools.partial` object.
1172+
"""
11631173
if args or kwargs:
1174+
cbook.warn_deprecated(
1175+
"3.1", "In a future version, Timer.remove_callback will not "
1176+
"take *args, **kwargs anymore, but remove all callbacks where "
1177+
"the callable matches; to keep a specific callback removable "
1178+
"by itself, pass it to add_callback as a functools.partial "
1179+
"object.")
11641180
self.callbacks.remove((func, args, kwargs))
11651181
else:
11661182
funcs = [c[0] for c in self.callbacks]
@@ -1174,11 +1190,11 @@ def _timer_set_single_shot(self):
11741190
"""Used to set single shot on underlying timer object."""
11751191

11761192
def _on_timer(self):
1177-
'''
1193+
"""
11781194
Runs all function that have been registered as callbacks. Functions
11791195
can return False (or 0) if they should not be called any more. If there
11801196
are no callbacks, the timer is automatically stopped.
1181-
'''
1197+
"""
11821198
for func, args, kwargs in self.callbacks:
11831199
ret = func(*args, **kwargs)
11841200
# docstring above explains why we use `if ret == 0` here,

0 commit comments

Comments
 (0)