Ticket #3439: dispatch-refactoring.patch
File dispatch-refactoring.patch, 6.8 KB (added by , 18 years ago) |
---|
-
django/dispatch/dispatcher.py
diff -urN django-orig/django/dispatch/dispatcher.py django-new/django/dispatch/dispatcher.py
old new 25 25 deletion, (considerably speeds up the cleanup process 26 26 vs. the original code.) 27 27 """ 28 from __future__ import generators29 28 import types, weakref 30 29 from django.dispatch import saferef, robustapply, errors 31 30 … … 33 32 __cvsid__ = "$Id: dispatcher.py,v 1.9 2005/09/17 04:55:57 mcfletch Exp $" 34 33 __version__ = "$Revision: 1.9 $"[11:-2] 35 34 36 try:37 True38 except NameError:39 True = 1==140 False = 1==041 35 42 36 class _Parameter: 43 37 """Used to represent default parameter values.""" … … 140 134 if weak: 141 135 receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) 142 136 senderkey = id(sender) 143 if connections.has_key(senderkey): 144 signals = connections[senderkey] 145 else: 146 connections[senderkey] = signals = {} 137 138 signals = connections.setdefault(senderkey, {}) 139 147 140 # Keep track of senders for cleanup. 148 141 # Is Anonymous something we want to clean up? 149 142 if sender not in (None, Anonymous, Any): … … 251 244 to retrieve the actual receiver objects as an iterable 252 245 object. 253 246 """ 254 try:255 return connections[id(sender)][signal]256 except KeyError:257 247 existing = connections.get(id(sender)) 248 if existing is not None: 249 return existing.get(signal, []) 250 return [] 258 251 259 252 def liveReceivers(receivers): 260 253 """Filter sequence of receivers to get resolved, live receivers … … 278 271 def getAllReceivers( sender = Any, signal = Any ): 279 272 """Get list of all receivers from global tables 280 273 281 This gets all receivers which should receive274 This gets all dereferenced receivers which should receive 282 275 the given signal from sender, each receiver should 283 276 be produced only once by the resulting generator 284 277 """ 285 278 receivers = {} 286 for set in ( 287 # Get receivers that receive *this* signal from *this* sender. 288 getReceivers( sender, signal ), 289 # Add receivers that receive *any* signal from *this* sender. 290 getReceivers( sender, Any ), 291 # Add receivers that receive *this* signal from *any* sender. 292 getReceivers( Any, signal ), 293 # Add receivers that receive *any* signal from *any* sender. 294 getReceivers( Any, Any ), 295 ): 296 for receiver in set: 297 if receiver: # filter out dead instance-method weakrefs 298 try: 299 if not receivers.has_key( receiver ): 300 receivers[receiver] = 1 301 yield receiver 302 except TypeError: 303 # dead weakrefs raise TypeError on hash... 304 pass 279 # Get receivers that receive *this* signal from *this* sender. 280 # Add receivers that receive *any* signal from *this* sender. 281 # Add receivers that receive *this* signal from *any* sender. 282 # Add receivers that receive *any* signal from *any* sender. 283 l = [] 284 i = id(sender) 285 if i in connections: 286 sender_receivers = connections[i] 287 if signal in sender_receivers: 288 l.extend(sender_receivers[signal]) 289 if signal is not Any and Any in sender_receivers: 290 l.extend(sender_receivers[Any]) 291 292 if sender is not Any: 293 i = id(Any) 294 if i in connections: 295 sender_receivers = connections[i] 296 if sender_receivers is not None: 297 if signal in sender_receivers: 298 l.extend(sender_receivers[signal]) 299 if signal is not Any and Any in sender_receivers: 300 l.extend(sender_receivers[Any]) 301 302 for receiver in l: 303 try: 304 if not receiver in receivers: 305 if isinstance(receiver, WEAKREF_TYPES): 306 receiver = receiver() 307 # this should only (rough guess) be possible if somehow, deref'ing 308 # triggered a wipe. 309 if receiver is None: 310 continue 311 receivers[receiver] = 1 312 yield receiver 313 except TypeError: 314 # dead weakrefs raise TypeError on hash... 315 pass 305 316 306 317 def send(signal=Any, sender=Anonymous, *arguments, **named): 307 318 """Send signal from sender to all connected receivers. … … 340 351 # Call each receiver with whatever arguments it can accept. 341 352 # Return a list of tuple pairs [(receiver, response), ... ]. 342 353 responses = [] 343 for receiver in liveReceivers(getAllReceivers(sender, signal)):354 for receiver in getAllReceivers(sender, signal): 344 355 response = robustapply.robustApply( 345 356 receiver, 346 357 signal=signal, … … 350 361 ) 351 362 responses.append((receiver, response)) 352 363 return responses 364 365 353 366 def sendExact( signal=Any, sender=Anonymous, *arguments, **named ): 354 367 """Send signal only to those receivers registered for exact message 355 368 … … 421 434 def _removeSender(senderkey): 422 435 """Remove senderkey from connections.""" 423 436 _removeBackrefs(senderkey) 424 try: 425 del connections[senderkey] 426 except KeyError: 427 pass 428 # Senderkey will only be in senders dictionary if sender 429 # could be weakly referenced. 430 try: 431 del senders[senderkey] 432 except: 433 pass 437 438 connections.pop(senderkey, None) 439 senders.pop(senderkey, None) 434 440 435 441 436 442 def _removeBackrefs( senderkey): 437 443 """Remove all back-references to this senderkey""" 438 try: 439 signals = connections[senderkey] 440 except KeyError: 441 signals = None 442 else: 443 items = signals.items() 444 def allReceivers( ): 445 for signal,set in items: 446 for item in set: 447 yield item 448 for receiver in allReceivers(): 444 connections.pop(senderkey, None) 445 for receiver_list in connections.pop(senderkey, {}).values(): 446 for receiver in receiver_list: 449 447 _killBackref( receiver, senderkey ) 450 448 449 451 450 def _removeOldBackRefs(senderkey, signal, receiver, receivers): 452 451 """Kill old sendersBack references from receiver 453 452 … … 483 482 def _killBackref( receiver, senderkey ): 484 483 """Do the actual removal of back reference from receiver to senderkey""" 485 484 receiverkey = id(receiver) 486 set = sendersBack.get( receiverkey, () )487 while senderkey in set:485 receivers_list = sendersBack.get( receiverkey, () ) 486 while senderkey in receivers_list: 488 487 try: 489 set.remove( senderkey )488 receivers_list.remove( senderkey ) 490 489 except: 491 490 break 492 if not set:491 if not receivers_list: 493 492 try: 494 493 del sendersBack[ receiverkey ] 495 494 except KeyError: