Changeset 4588
- Timestamp:
- 02/25/07 21:17:04 (2 years ago)
- Files:
-
- django/trunk/django/dispatch/dispatcher.py (modified) (9 diffs)
- django/trunk/tests/regressiontests/dispatch (added)
- django/trunk/tests/regressiontests/dispatch/__init__.py (added)
- django/trunk/tests/regressiontests/dispatch/models.py (added)
- django/trunk/tests/regressiontests/dispatch/tests (added)
- django/trunk/tests/regressiontests/dispatch/tests/__init__.py (added)
- django/trunk/tests/regressiontests/dispatch/tests/test_dispatcher.py (added)
- django/trunk/tests/regressiontests/dispatch/tests/test_robustapply.py (added)
- django/trunk/tests/regressiontests/dispatch/tests/test_saferef.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/dispatch/dispatcher.py
r4265 r4588 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 … … 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: … … 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? … … 252 245 object. 253 246 """ 254 try:255 return connections[id(sender)][signal]256 except KeyError:257 return []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): … … 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): … … 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, … … 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 … … 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 for receiver_list in connections.pop(senderkey, {}).values(): 445 for receiver in receiver_list: 449 446 _killBackref( receiver, senderkey ) 447 450 448 451 449 def _removeOldBackRefs(senderkey, signal, receiver, receivers): … … 484 482 """Do the actual removal of back reference from receiver to senderkey""" 485 483 receiverkey = id(receiver) 486 set = sendersBack.get( receiverkey, () )487 while senderkey in set:484 receivers_list = sendersBack.get( receiverkey, () ) 485 while senderkey in receivers_list: 488 486 try: 489 set.remove( senderkey )487 receivers_list.remove( senderkey ) 490 488 except: 491 489 break 492 if not set:490 if not receivers_list: 493 491 try: 494 492 del sendersBack[ receiverkey ]
