8000 Fixed bug in cbook.CallbackRegistry and cleaned it up a little with b… · fariza/matplotlib@0040d25 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0040d25

Browse files
committed
Fixed bug in cbook.CallbackRegistry and cleaned it up a little with better gc.
1 parent 7683b0b commit 0040d25

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

lib/matplotlib/cbook.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,11 @@ class _BoundMethodProxy(object):
361361
Minor bugfixes by Michael Droettboom
362362
'''
363363
def __init__(self, cb):
364+
self._hash = hash(cb)
365+
self._callbacks = []
364366
try:
365367
try:
366-
self.inst = ref(cb.im_self)
368+
self.inst = ref(cb.im_self, self._destroy)
367369
except TypeError:
368370
self.inst = None
369371
if six.PY3:
@@ -377,6 +379,13 @@ def __init__(self, cb):
377379
self.func = cb
378380
self.klass = None
379381

382+
def add_callback(self, callback):
383+
self._callbacks.append(_BoundMethodProxy(callback))
384+
385+
def _destroy(self, wk):
386+
for callback in self._callbacks:
387+
callback(self)
388+
380389
def __getstate__(self):
381390
d = self.__dict__.copy()
382391
# de-weak reference inst
@@ -433,6 +442,9 @@ def __ne__(self, other):
433442
'''
434443
return not self.__eq__(other)
435444

445+
def __hash__(self):
446+
return self._hash
447+
436448

437449
class CallbackRegistry(object):
438450
"""
@@ -492,17 +504,24 @@ def connect(self, s, func):
492504
func will be called
493505
"""
494506
self._func_cid_map.setdefault(s, WeakKeyDictionary())
495-
if func in self._func_cid_map[s]:
496-
return self._func_cid_map[s][func]
507+
proxy = _BoundMethodProxy(func)
508+
if proxy in self._func_cid_map[s]:
509+
return self._func_cid_map[s][proxy]
497510

511+
proxy.add_callback(self.remove_proxy)
498512
self._cid += 1
499513
cid = self._cid
500-
self._func_cid_map[s][func] = cid
514+
self._func_cid_map[s][proxy] = cid
501515
self.callbacks.setdefault(s, dict())
502-
proxy = _BoundMethodProxy(func)
503516
self.callbacks[s][cid] = proxy
504517
return cid
505518

519+
def remove_proxy(self, proxy):
520+
"""Removes a dead proxy as soon as it dies"""
521+
for category, proxies in list(six.iteritems(self._func_cid_map)):
522+
if proxy in proxies:
523+
del self.callbacks[category][proxies[proxy]]
524+
506525
def disconnect(self, cid):
507526
"""
508527
disconnect the callback registered with callback id *cid*
@@ -527,11 +546,7 @@ def process(self, s, *args, **kwargs):
527546
"""
528547
if s in self.callbacks:
529548
for cid, proxy in list(six.iteritems(self.callbacks[s])):
530-
# Clean out dead references
531-
if proxy.inst is not None and proxy.inst() is None:
532-
del self.callbacks[s][cid]
533-
else:
534-
proxy(*args, **kwargs)
549+
proxy(*args, **kwargs)
535550

536551

537552
class Scheduler(threading.Thread):

0 commit comments

Comments
 (0)
0