Code

Ticket #3439: dispatch-refactoring.patch

File dispatch-refactoring.patch, 6.8 KB (added by (removed), 7 years ago)

dispatcher refactoring round 1.

  • django/dispatch/dispatcher.py

    diff -urN django-orig/django/dispatch/dispatcher.py django-new/django/dispatch/dispatcher.py
    old new  
    2525        deletion, (considerably speeds up the cleanup process 
    2626        vs. the original code.) 
    2727""" 
    28 from __future__ import generators 
    2928import types, weakref 
    3029from django.dispatch import saferef, robustapply, errors 
    3130 
     
    3332__cvsid__ = "$Id: dispatcher.py,v 1.9 2005/09/17 04:55:57 mcfletch Exp $" 
    3433__version__ = "$Revision: 1.9 $"[11:-2] 
    3534 
    36 try: 
    37     True 
    38 except NameError: 
    39     True = 1==1 
    40     False = 1==0 
    4135 
    4236class _Parameter: 
    4337    """Used to represent default parameter values.""" 
     
    140134    if weak: 
    141135        receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) 
    142136    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 
    147140    # Keep track of senders for cleanup. 
    148141    # Is Anonymous something we want to clean up? 
    149142    if sender not in (None, Anonymous, Any): 
     
    251244    to retrieve the actual receiver objects as an iterable 
    252245    object. 
    253246    """ 
    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 [] 
    258251 
    259252def liveReceivers(receivers): 
    260253    """Filter sequence of receivers to get resolved, live receivers 
     
    278271def getAllReceivers( sender = Any, signal = Any ): 
    279272    """Get list of all receivers from global tables 
    280273 
    281     This gets all receivers which should receive 
     274    This gets all dereferenced receivers which should receive 
    282275    the given signal from sender, each receiver should 
    283276    be produced only once by the resulting generator 
    284277    """ 
    285278    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 
    305316 
    306317def send(signal=Any, sender=Anonymous, *arguments, **named): 
    307318    """Send signal from sender to all connected receivers. 
     
    340351    # Call each receiver with whatever arguments it can accept. 
    341352    # Return a list of tuple pairs [(receiver, response), ... ]. 
    342353    responses = [] 
    343     for receiver in liveReceivers(getAllReceivers(sender, signal)): 
     354    for receiver in getAllReceivers(sender, signal): 
    344355        response = robustapply.robustApply( 
    345356            receiver, 
    346357            signal=signal, 
     
    350361        ) 
    351362        responses.append((receiver, response)) 
    352363    return responses 
     364 
     365 
    353366def sendExact( signal=Any, sender=Anonymous, *arguments, **named ): 
    354367    """Send signal only to those receivers registered for exact message 
    355368 
     
    421434def _removeSender(senderkey): 
    422435    """Remove senderkey from connections.""" 
    423436    _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) 
    434440 
    435441 
    436442def _removeBackrefs( senderkey): 
    437443    """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: 
    449447            _killBackref( receiver, senderkey ) 
    450448 
     449 
    451450def _removeOldBackRefs(senderkey, signal, receiver, receivers): 
    452451    """Kill old sendersBack references from receiver 
    453452 
     
    483482def _killBackref( receiver, senderkey ): 
    484483    """Do the actual removal of back reference from receiver to senderkey""" 
    485484    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: 
    488487        try: 
    489             set.remove( senderkey ) 
     488            receivers_list.remove( senderkey ) 
    490489        except: 
    491490            break 
    492     if not set: 
     491    if not receivers_list: 
    493492        try: 
    494493            del sendersBack[ receiverkey ] 
    495494        except KeyError: