Ticket #3439: dispatch-refactoring.patch

File dispatch-refactoring.patch, 6.8 KB (added by (removed), 17 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:
Back to Top