Ticket #9015: signal_deco_patch.diff

File signal_deco_patch.diff, 6.5 KB (added by zvoase, 11 years ago)

Patch-v1.diff

  • dispatcher.py

     
    2929            providing_args = []
    3030        self.providing_args = set(providing_args)
    3131
    32     def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
    33         """Connect receiver to sender for signal
    34    
    35         receiver -- a function or an instance method which is to
    36             receive signals.  Receivers must be
    37             hashable objects.
     32        def connect(self, *args, **kwargs):
     33                """Decorate a receiver, connecting it to sender for signal."""
     34                if args:
     35                        self._connect(*args, **kwargs)
     36                        # Return the receiver, if being used for decoration.
     37                        return args[0]
     38                def connection_wrapper(receiver):
     39                        self._connect(receiver, **kwargs)
     40                        return receiver
     41                return connection_wrapper
    3842
    39             if weak is True, then receiver must be weak-referencable
    40             (more precisely saferef.safeRef() must be able to create
    41             a reference to the receiver).
    42        
    43             Receivers must be able to accept keyword arguments.
    44 
    45             If receivers have a dispatch_uid attribute, the receiver will
    46               not be added if another receiver already exists with that
    47               dispatch_uid.
    48 
    49         sender -- the sender to which the receiver should respond
    50             Must either be of type Signal, or None to receive events
    51             from any sender.
    52 
    53         weak -- whether to use weak references to the receiver
    54             By default, the module will attempt to use weak
    55             references to the receiver objects.  If this parameter
    56             is false, then strong references will be used.
    57        
    58         dispatch_uid -- an identifier used to uniquely identify a particular
    59             instance of a receiver. This will usually be a string, though it
    60             may be anything hashable.
    61 
    62         returns None
    63         """
    64         from django.conf import settings
    65        
    66         # If DEBUG is on, check that we got a good receiver
    67         if settings.DEBUG:
    68             import inspect
    69             assert callable(receiver), "Signal receivers must be callable."
    70            
    71             # Check for **kwargs
    72             # Not all callables are inspectable with getargspec, so we'll
    73             # try a couple different ways but in the end fall back on assuming
    74             # it is -- we don't want to prevent registration of valid but weird
    75             # callables.
    76             try:
    77                 argspec = inspect.getargspec(receiver)
    78             except TypeError:
    79                 try:
    80                     argspec = inspect.getargspec(receiver.__call__)
    81                 except (TypeError, AttributeError):
    82                     argspec = None
    83             if argspec:
    84                 assert argspec[2] is not None, \
    85                     "Signal receivers must accept keyword arguments (**kwargs)."
    86        
    87         if dispatch_uid:
    88             lookup_key = (dispatch_uid, _make_id(sender))
    89         else:
    90             lookup_key = (_make_id(receiver), _make_id(sender))
    91 
    92         if weak:
    93             receiver = saferef.safeRef(receiver, onDelete=self._remove_receiver)
    94 
    95         for r_key, _ in self.receivers:
    96             if r_key == lookup_key:
    97                 break
    98         else:
    99             self.receivers.append((lookup_key, receiver))
    100 
    10143    def disconnect(self, receiver=None, sender=None, weak=True, dispatch_uid=None):
    10244        """Disconnect receiver from sender for signal
    10345   
     
    182124                responses.append((receiver, response))
    183125        return responses
    184126
     127    def _connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
     128        """Connect receiver to sender for signal
     129
     130        receiver -- a function or an instance method which is to
     131            receive signals.  Receivers must be
     132            hashable objects.
     133
     134            if weak is True, then receiver must be weak-referencable
     135            (more precisely saferef.safeRef() must be able to create
     136            a reference to the receiver).
     137
     138            Receivers must be able to accept keyword arguments.
     139
     140            If receivers have a dispatch_uid attribute, the receiver will
     141              not be added if another receiver already exists with that
     142              dispatch_uid.
     143
     144        sender -- the sender to which the receiver should respond
     145            Must either be of type Signal, or None to receive events
     146            from any sender.
     147
     148        weak -- whether to use weak references to the receiver
     149            By default, the module will attempt to use weak
     150            references to the receiver objects.  If this parameter
     151            is false, then strong references will be used.
     152
     153        dispatch_uid -- an identifier used to uniquely identify a particular
     154            instance of a receiver. This will usually be a string, though it
     155            may be anything hashable.
     156
     157        returns None
     158        """
     159        from django.conf import settings
     160
     161        # If DEBUG is on, check that we got a good receiver
     162        if settings.DEBUG:
     163            import inspect
     164            assert callable(receiver), "Signal receivers must be callable."
     165
     166            # Check for **kwargs
     167            # Not all callables are inspectable with getargspec, so we'll
     168            # try a couple different ways but in the end fall back on assuming
     169            # it is -- we don't want to prevent registration of valid but weird
     170            # callables.
     171            try:
     172                argspec = inspect.getargspec(receiver)
     173            except TypeError:
     174                try:
     175                    argspec = inspect.getargspec(receiver.__call__)
     176                except (TypeError, AttributeError):
     177                    argspec = None
     178            if argspec:
     179                assert argspec[2] is not None, \
     180                    "Signal receivers must accept keyword arguments (**kwargs)."
     181
     182        if dispatch_uid:
     183            lookup_key = (dispatch_uid, _make_id(sender))
     184        else:
     185            lookup_key = (_make_id(receiver), _make_id(sender))
     186
     187        if weak:
     188            receiver = saferef.safeRef(receiver, onDelete=self._remove_receiver)
     189
     190        for r_key, _ in self.receivers:
     191            if r_key == lookup_key:
     192                break
     193        else:
     194            self.receivers.append((lookup_key, receiver))
     195
    185196    def _live_receivers(self, senderkey):
    186197        """Filter sequence of receivers to get resolved, live receivers
    187198
Back to Top