@@ -171,7 +171,7 @@ class CallbackRegistry:
171
171
172
172
# We maintain two mappings:
173
173
# callbacks: signal -> {cid -> weakref-to-callback}
174
- # _func_cid_map: signal -> { weakref-to-callback -> cid}
174
+ # _func_cid_map: {( signal, weakref-to-callback) -> cid}
175
175
176
176
def __init__ (self , exception_handler = _exception_printer , * , signals = None ):
177
177
self ._signals = None if signals is None else list (signals ) # Copy it.
@@ -203,23 +203,21 @@ def __setstate__(self, state):
203
203
for cid , func in d .items ()}
204
204
for s , d in self .callbacks .items ()}
205
205
self ._func_cid_map = {
206
- s : { proxy : cid for cid , proxy in d . items ()}
207
- for s , d in self .callbacks .items ()}
206
+ ( s , proxy ) : cid
207
+ for s , d in self .callbacks .items () for cid , proxy in d . items () }
208
208
self ._cid_gen = itertools .count (cid_count )
209
209
210
210
def connect (self , signal , func ):
211
211
"""Register *func* to be called when signal *signal* is generated."""
212
212
if self ._signals is not None :
213
213
_api .check_in_list (self ._signals , signal = signal )
214
- self ._func_cid_map .setdefault (signal , {})
215
214
proxy = _weak_or_strong_ref (func , functools .partial (self ._remove_proxy , signal ))
216
- if proxy in self ._func_cid_map [signal ]:
217
- return self ._func_cid_map [signal ][proxy ]
218
- cid = next (self ._cid_gen )
219
- self ._func_cid_map [signal ][proxy ] = cid
220
- self .callbacks .setdefault (signal , {})
221
- self .callbacks [signal ][cid ] = proxy
222
- return cid
215
+ try :
216
+ return self ._func_cid_map [signal , proxy ]
217
+ except KeyError :
218
+ cid = self ._func_cid_map [signal , proxy ] = next (self ._cid_gen )
219
+ self .callbacks .setdefault (signal , {})[cid ] = proxy
220
+ return cid
223
221
224
222
def _connect_picklable (self , signal , func ):
225
223
"""
@@ -237,16 +235,14 @@ def _remove_proxy(self, signal, proxy, *, _is_finalizing=sys.is_finalizing):
237
235
if _is_finalizing ():
238
236
# Weakrefs can't be properly torn down at that point anymore.
239
237
return
240
- cid = self ._func_cid_map [ signal ] .pop (proxy , None )
238
+ cid = self ._func_cid_map .pop (( signal , proxy ) , None )
241
239
if cid is not None :
242
240
del self .callbacks [signal ][cid ]
243
241
self ._pickled_cids .discard (cid )
244
242
else : # Not found
245
243
return
246
- # Clean up empty dicts
247
- if len (self .callbacks [signal ]) == 0 :
244
+ if len (self .callbacks [signal ]) == 0 : # Clean up empty dicts
248
245
del self .callbacks [signal ]
249
- del self ._func_cid_map [signal ]
250
246
251
247
def disconnect (self , cid ):
252
248
"""
@@ -255,22 +251,16 @@ def disconnect(self, cid):
255
251
No error is raised if such a callback does not exist.
256
252
"""
257
253
self ._pickled_cids .discard (cid )
258
- # Clean up callbacks
259
- for signal , cid_to_proxy in list (self .callbacks .items ()):
260
- proxy = cid_to_proxy .pop (cid , None )
261
- if proxy is not None :
254
+ for signal , proxy in self ._func_cid_map :
255
+ if self ._func_cid_map [signal , proxy ] == cid :
262
256
break
263
257
else : # Not found
264
258
return
265
- proxy_to_cid = self ._func_cid_map [signal ]
266
- for current_proxy , current_cid in list (proxy_to_cid .items ()):
267
- if current_cid == cid :
268
- assert proxy is current_proxy
269
- del proxy_to_cid [current_proxy ]
270
- # Clean up empty dicts
271
- if len (self .callbacks [signal ]) == 0 :
259
+ assert self .callbacks [signal ][cid ] == proxy
260
+ del self .callbacks [signal ][cid ]
261
+ del self ._func_cid_map [signal , proxy ]
262
+ if len (self .callbacks [signal ]) == 0 : # Clean up empty dicts
272
263
del self .callbacks [signal ]
273
- del self ._func_cid_map [signal ]
274
264
275
265
def process (self , s , * args , ** kwargs ):
276
266
"""
0 commit comments