示例#1
0
 def test_ShortCircuit(self):
     """Test that creation short-circuits to reuse existing references"""
     sd = {}
     for s in self.ss:
         sd[s] = 1
     for t in self.ts:
         if hasattr(t, 'x'):
             assert safe_ref(t.x) in sd
         else:
             assert safe_ref(t) in sd
示例#2
0
 def test_ShortCircuit(self):
     """Test that creation short-circuits to reuse existing references"""
     sd = {}
     for s in self.ss:
         sd[s] = 1
     for t in self.ts:
         if hasattr(t, 'x'):
             assert sd.has_key(safe_ref(t.x))
         else:
             assert sd.has_key(safe_ref(t))
示例#3
0
 def unregister_callback(self, callback):
     cb_ref = saferef.safe_ref(callback)
     try:
         callback_refs = CHANNELS_CBK.setdefault(self.__name, set())
         callback_refs.remove(cb_ref)
     except:
         return
示例#4
0
 def unregister_callback(self, callback):
     cb_ref = saferef.safe_ref(callback)
     try:
         callback_refs = CHANNELS_CBK.setdefault(self.__name,set())
         callback_refs.remove(cb_ref)
     except:
         return
示例#5
0
 def setUp(self):
     ts = []
     ss = []
     self.closure_count = 0
     self.ts = ts
     self.ss = ss
     for x in range(5000):
         t = _Sample1()
         ts.append(t)
         s = safe_ref(t.x, self._closure)
         ss.append(s)
     ts.append(_sample2)
     ss.append(safe_ref(_sample2, self._closure))
     for x in range(30):
         t = _Sample3()
         ts.append(t)
         s = safe_ref(t, self._closure)
         ss.append(s)
示例#6
0
 def setUp(self):
     ts = []
     ss = []
     self.closure_count = 0
     self.ts = ts
     self.ss = ss
     for x in range(5000):
         t = _Sample1()
         ts.append(t)
         s = safe_ref(t.x, self._closure)
         ss.append(s)
     ts.append(_sample2)
     ss.append(safe_ref(_sample2, self._closure))
     for x in range(30):
         t = _Sample3()
         ts.append(t)
         s = safe_ref(t, self._closure)
         ss.append(s)
示例#7
0
def disconnect(receiver, signal=All, sender=Any, weak=True):
    """Disconnect ``receiver`` from ``sender`` for ``signal``.

    - ``receiver``: The registered receiver to disconnect.
    
    - ``signal``: The registered signal to disconnect.
    
    - ``sender``: The registered sender to disconnect.
    
    - ``weak``: The weakref state to disconnect.

    ``disconnect`` reverses the process of ``connect``, the semantics for
    the individual elements are logically equivalent to a tuple of
    ``(receiver, signal, sender, weak)`` used as a key to be deleted
    from the internal routing tables.  (The actual process is slightly
    more complex but the semantics are basically the same).

    Note: Using ``disconnect`` is not required to cleanup routing when
    an object is deleted; the framework will remove routes for deleted
    objects automatically.  It's only necessary to disconnect if you
    want to stop routing to a live object.
        
    Returns ``None``, may raise ``DispatcherTypeError`` or
    ``DispatcherKeyError``.
    """
    if signal is None:
        raise error.DispatcherTypeError(
            'Signal cannot be None (receiver=%r sender=%r)'
            % (receiver, sender))
    if weak:
        receiver = saferef.safe_ref(receiver)
    senderkey = id(sender)
    try:
        signals = connections[senderkey]
        receivers = signals[signal]
    except KeyError:
        raise error.DispatcherKeyError(
            'No receivers found for signal %r from sender %r' 
            % (signal, sender)
            )
    try:
        # also removes from receivers
        _remove_old_back_refs(senderkey, signal, receiver, receivers)
    except ValueError:
        raise error.DispatcherKeyError(
            'No connection to receiver %s for signal %s from sender %s'
            % (receiver, signal, sender)
            )
    _cleanup_connections(senderkey, signal)
    # Update stats.
    if __debug__:
        global disconnects
        disconnects += 1
示例#8
0
def disconnect(receiver, signal=All, sender=Any, weak=True):
    """Disconnect ``receiver`` from ``sender`` for ``signal``.

    - ``receiver``: The registered receiver to disconnect.
    
    - ``signal``: The registered signal to disconnect.
    
    - ``sender``: The registered sender to disconnect.
    
    - ``weak``: The weakref state to disconnect.

    ``disconnect`` reverses the process of ``connect``, the semantics for
    the individual elements are logically equivalent to a tuple of
    ``(receiver, signal, sender, weak)`` used as a key to be deleted
    from the internal routing tables.  (The actual process is slightly
    more complex but the semantics are basically the same).

    Note: Using ``disconnect`` is not required to cleanup routing when
    an object is deleted; the framework will remove routes for deleted
    objects automatically.  It's only necessary to disconnect if you
    want to stop routing to a live object.
        
    Returns ``None``, may raise ``DispatcherTypeError`` or
    ``DispatcherKeyError``.
    """
    if signal is None:
        raise error.DispatcherTypeError(
            'Signal cannot be None (receiver=%r sender=%r)'
            % (receiver, sender))
    if weak:
        receiver = saferef.safe_ref(receiver)
    senderkey = id(sender)
    try:
        signals = connections[senderkey]
        receivers = signals[signal]
    except KeyError:
        raise error.DispatcherKeyError(
            'No receivers found for signal %r from sender %r' 
            % (signal, sender)
            )
    try:
        # also removes from receivers
        _remove_old_back_refs(senderkey, signal, receiver, receivers)
    except ValueError:
        raise error.DispatcherKeyError(
            'No connection to receiver %s for signal %s from sender %s'
            % (receiver, signal, sender)
            )
    _cleanup_connections(senderkey, signal)
    # Update stats.
    if __debug__:
        global disconnects
        disconnects += 1
示例#9
0
def connect(handler, signal, sender=dispatcher.Any, priority=0):
    """
    Connects a callback to a signal, so that the callback will be automatically invoked
    when that signal is sent.

    Parameters:

        :handler: This can be any callable that that takes the right arguments for
                  the signal. For most signals this means a single argument that
                  will be an ``ExecutionContext`` instance. But please see documentation
                  for individual signals in the :ref:`signals reference <instruments_method_map>`.
        :signal: The signal to which the handler will be subscribed. Please see
                 :ref:`signals reference <instruments_method_map>` for the list of standard WA
                 signals.

                 .. note:: There is nothing that prevents instruments from sending their
                           own signals that are not part of the standard set. However the signal
                           must always be an :class:`wa.core.signal.Signal` instance.

        :sender: The handler will be invoked only for the signals emitted by this sender. By
                 default, this is set to :class:`louie.dispatcher.Any`, so the handler will
                 be invoked for signals from any sender.
        :priority: An integer (positive or negative) the specifies the priority of the handler.
                   Handlers with higher priority will be called before handlers with lower
                   priority. The  call order of handlers with the same priority is not specified.
                   Defaults to 0.

                   .. note:: Priorities for some signals are inverted (so highest priority
                             handlers get executed last). Please see :ref:`signals reference <instruments_method_map>`
                             for details.

    """
    logger.debug('Connecting {} to {}({}) with priority {}'.format(
        handler, signal, sender, priority))
    if getattr(signal, 'invert_priority', False):
        priority = -priority
    senderkey = id(sender)
    if senderkey in dispatcher.connections:
        signals = dispatcher.connections[senderkey]
    else:
        dispatcher.connections[senderkey] = signals = {}
    if signal in signals:
        receivers = signals[signal]
    else:
        receivers = signals[signal] = _prioritylist_wrapper()
    dispatcher.connect(handler, signal, sender)
    receivers.add(saferef.safe_ref(handler, on_delete=_remove_receiver),
                  priority)
示例#10
0
文件: signal.py 项目: ask/louie
    def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
        """Connect receiver to sender for signal.

        :param receiver: A function or an instance method which is to
            receive signals. Receivers must be hashable objects.

            if weak is ``True``, then receiver must be weak-referencable (more
            precisely :func:`saferef.safe_ref()` must be able to create a reference
            to the receiver).

            Receivers must be able to accept keyword arguments.

            If receivers have a ``dispatch_uid`` attribute, the receiver will
            not be added if another receiver already exists with that
            ``dispatch_uid``.

        :keyword sender: The sender to which the receiver should respond.
            Must either be of type :class:`Signal`, or ``None`` to receive
            events from any sender.

        :keyword weak: Whether to use weak references to the receiver.
            By default, the module will attempt to use weak references to the
            receiver objects. If this parameter is false, then strong
            references will be used.

        :keyword dispatch_uid: An identifier used to uniquely identify a
            particular instance of a receiver. This will usually be a
            string, though it may be anything hashable.

        """
        if dispatch_uid:
            lookup_key = (dispatch_uid, _make_id(sender))
        else:
            lookup_key = (_make_id(receiver), _make_id(sender))

        if weak:
            receiver = saferef.safe_ref(receiver, on_delete=self._remove_receiver)

        for r_key, _ in self.receivers:
            if r_key == lookup_key:
                break
        else:
            self.receivers.append((lookup_key, receiver))
示例#11
0
def connect(receiver, signal=All, sender=Any, weak=True):
    """Connect ``receiver`` to ``sender`` for ``signal``.

    - ``receiver``: A callable Python object which is to receive
      messages/signals/events.  Receivers must be hashable objects.

      If weak is ``True``, then receiver must be weak-referencable (more
      precisely ``saferef.safe_ref()`` must be able to create a
      reference to the receiver).

      Receivers are fairly flexible in their specification, as the
      machinery in the ``robustapply`` module takes care of most of the
      details regarding figuring out appropriate subsets of the sent
      arguments to apply to a given receiver.

      Note: If ``receiver`` is itself a weak reference (a callable), it
      will be de-referenced by the system's machinery, so *generally*
      weak references are not suitable as receivers, though some use
      might be found for the facility whereby a higher-level library
      passes in pre-weakrefed receiver references.

    - ``signal``: The signal to which the receiver should respond.

      If ``All``, receiver will receive all signals from the indicated
      sender (which might also be ``All``, but is not necessarily
      ``All``).

      Otherwise must be a hashable Python object other than ``None``
      (``DispatcherError`` raised on ``None``).

    - ``sender``: The sender to which the receiver should respond.

      If ``Any``, receiver will receive the indicated signals from any
      sender.

      If ``Anonymous``, receiver will only receive indicated signals
      from ``send``/``send_exact`` which do not specify a sender, or
      specify ``Anonymous`` explicitly as the sender.

      Otherwise can be any python object.

    - ``weak``: Whether to use weak references to the receiver.

      By default, the module will attempt to use weak references to
      the receiver objects.  If this parameter is ``False``, then strong
      references will be used.

    Returns ``None``, may raise ``DispatcherTypeError``.
    """
    if signal is None:
        raise error.DispatcherTypeError(
            f"Signal cannot be None (receiver={receiver!r} sender={sender!r})")
    if weak:
        receiver = saferef.safe_ref(receiver, on_delete=_remove_receiver)
    senderkey = id(sender)
    if senderkey in connections:
        signals = connections[senderkey]
    else:
        connections[senderkey] = signals = {}
    # Keep track of senders for cleanup.
    # Is Anonymous something we want to clean up?
    if sender not in (None, Anonymous, Any):

        def remove(object, senderkey=senderkey):
            _remove_sender(senderkey=senderkey)

        # Skip objects that can not be weakly referenced, which means
        # they won't be automatically cleaned up, but that's too bad.
        try:
            weak_sender = weakref.ref(sender, remove)
            senders[senderkey] = weak_sender
        except Exception:
            pass
    receiver_id = id(receiver)
    # get current set, remove any current references to
    # this receiver in the set, including back-references
    if signal in signals:
        receivers = signals[signal]
        _remove_old_back_refs(senderkey, signal, receiver, receivers)
    else:
        receivers = signals[signal] = []
    try:
        current = senders_back.get(receiver_id)
        if current is None:
            senders_back[receiver_id] = current = []
        if senderkey not in current:
            current.append(senderkey)
    except Exception:
        pass
    receivers.append(receiver)
    # Update stats.
    if __debug__:
        global connects
        connects += 1
示例#12
0
def connect(receiver, signal=All, sender=Any, weak=True):
    """Connect ``receiver`` to ``sender`` for ``signal``.

    - ``receiver``: A callable Python object which is to receive
      messages/signals/events.  Receivers must be hashable objects.

      If weak is ``True``, then receiver must be weak-referencable (more
      precisely ``saferef.safe_ref()`` must be able to create a
      reference to the receiver).
    
      Receivers are fairly flexible in their specification, as the
      machinery in the ``robustapply`` module takes care of most of the
      details regarding figuring out appropriate subsets of the sent
      arguments to apply to a given receiver.

      Note: If ``receiver`` is itself a weak reference (a callable), it
      will be de-referenced by the system's machinery, so *generally*
      weak references are not suitable as receivers, though some use
      might be found for the facility whereby a higher-level library
      passes in pre-weakrefed receiver references.

    - ``signal``: The signal to which the receiver should respond.
    
      If ``All``, receiver will receive all signals from the indicated
      sender (which might also be ``All``, but is not necessarily
      ``All``).
        
      Otherwise must be a hashable Python object other than ``None``
      (``DispatcherError`` raised on ``None``).
        
    - ``sender``: The sender to which the receiver should respond.
    
      If ``Any``, receiver will receive the indicated signals from any
      sender.
        
      If ``Anonymous``, receiver will only receive indicated signals
      from ``send``/``send_exact`` which do not specify a sender, or
      specify ``Anonymous`` explicitly as the sender.

      Otherwise can be any python object.
        
    - ``weak``: Whether to use weak references to the receiver.
      
      By default, the module will attempt to use weak references to
      the receiver objects.  If this parameter is ``False``, then strong
      references will be used.

    Returns ``None``, may raise ``DispatcherTypeError``.
    """
    if signal is None:
        raise error.DispatcherTypeError(
            'Signal cannot be None (receiver=%r sender=%r)'
            % (receiver, sender))
    if weak:
        receiver = saferef.safe_ref(receiver, on_delete=_remove_receiver)
    senderkey = id(sender)
    if connections.has_key(senderkey):
        signals = connections[senderkey]
    else:
        connections[senderkey] = signals = {}
    # Keep track of senders for cleanup.
    # Is Anonymous something we want to clean up?
    if sender not in (None, Anonymous, Any):
        def remove(object, senderkey=senderkey):
            _remove_sender(senderkey=senderkey)
        # Skip objects that can not be weakly referenced, which means
        # they won't be automatically cleaned up, but that's too bad.
        try:
            weak_sender = weakref.ref(sender, remove)
            senders[senderkey] = weak_sender
        except:
            pass
    receiver_id = id(receiver)
    # get current set, remove any current references to
    # this receiver in the set, including back-references
    if signals.has_key(signal):
        receivers = signals[signal]
        _remove_old_back_refs(senderkey, signal, receiver, receivers)
    else:
        receivers = signals[signal] = []
    try:
        current = senders_back.get(receiver_id)
        if current is None:
            senders_back[receiver_id] = current = []
        if senderkey not in current:
            current.append(senderkey)
    except:
        pass
    receivers.append(receiver)
    # Update stats.
    if __debug__:
        global connects
        connects += 1
示例#13
0
 def register_callback(self, callback):
     if callable(callback):
         cb_ref = saferef.safe_ref(callback)
         self._callback_refs.add(cb_ref)
示例#14
0
 def unregister_callback(self, callback):
     cb_ref = saferef.safe_ref(callback)
     try:
         self._callback_refs.remove(cb_ref)
     except:
         return
示例#15
0
 def register_callback(self, callback):
     if callable(callback):
         cb_ref = saferef.safe_ref(callback)
         self._callback_refs.add(cb_ref)
示例#16
0
 def test_In(self):
     """Test the `in` operator for safe references (cmp)"""
     for t in self.ts[:50]:
         assert safe_ref(t.x) in self.ss
示例#17
0
 def unregister_callback(self, callback):
     cb_ref = saferef.safe_ref(callback)
     try:
         self._callback_refs.remove(cb_ref)
     except:
         return
示例#18
0
 def test_In(self):
     """Test the `in` operator for safe references (cmp)"""
     for t in self.ts[:50]:
         assert safe_ref(t.x) in self.ss
示例#19
0
 def register_callback(self, callback):
     if callable(callback):
         cb_ref = saferef.safe_ref(callback)
         callback_refs = CHANNELS_CBK.setdefault(self.__name,set())
         callback_refs.add(cb_ref)
示例#20
0
 def register_callback(self, callback):
     if callable(callback):
         cb_ref = saferef.safe_ref(callback)
         callback_refs = CHANNELS_CBK.setdefault(self.__name, set())
         callback_refs.add(cb_ref)