
CQ9                 @   s   d  Z  d d l m Z d d l m Z d d l m Z m Z m Z m	 Z	 m
 Z
 m Z m Z e d  Z d e _  d Z Gd d   d e  Z e d	  Z Gd
 d   d e  Z Gd d   d e  Z Gd d   d e  Z e   j Z d S)a+  Signals and events.

A small implementation of signals, inspired by a snippet of Django signal
API client code seen in a blog post.  Signals are first-class objects and
each manages its own receivers and message emission.

The :func:`signal` function provides singleton behavior for named signals.

    )warn)WeakValueDictionary)	WeakTypescontextmanagerdefaultdicthashable_identitylazy_property	referencesymbolANYzToken for "any sender".c               @   s   e  Z d  Z d Z e Z e d d    Z e d d    Z d d d  Z e d	 d
 d  Z	 d d d  Z
 e e d d   Z e d d  Z d d   Z d d   Z d d   Z e d d  Z d d   Z d d   Z d d    Z d! d"   Z d S)#SignalzA notification emitter.c             C   s   t  d d  S)zEmitted after each :meth:`connect`.

        The signal sender is the signal instance, and the :meth:`connect`
        arguments are passed through: *receiver*, *sender*, and *weak*.

        .. versionadded:: 1.2

        docz"Emitted after a receiver connects.)r   )self r   ./usr/lib/python3/dist-packages/blinker/base.pyreceiver_connected%   s    
zSignal.receiver_connectedc             C   s   t  d d  S)a  Emitted after :meth:`disconnect`.

        The sender is the signal instance, and the :meth:`disconnect` arguments
        are passed through: *receiver* and *sender*.

        Note, this signal is emitted **only** when :meth:`disconnect` is
        called explicitly.

        The disconnect signal can not be emitted by an automatic disconnect
        (due to a weakly referenced receiver or sender going out of scope),
        as the receiver and/or sender instances are no longer available for
        use at the time this signal would be emitted.

        An alternative approach is available by subscribing to
        :attr:`receiver_connected` and setting up a custom weakref cleanup
        callback on weak receivers and senders.

        .. versionadded:: 1.2

        r   z%Emitted after a receiver disconnects.)r   )r   r   r   r   receiver_disconnected1   s    zSignal.receiver_disconnectedNc             C   sC   | r | |  _  i  |  _ t t  |  _ t t  |  _ i  |  _ d S)zt
        :param doc: optional.  If provided, will be assigned to the signal's
          __doc__ attribute.

        N)__doc__	receiversr   set_by_receiver
_by_sender_weak_senders)r   r   r   r   r   __init__I   s    		zSignal.__init__Tc             C   s  t  |  } | r0 t | |  j  } | | _ n | } | t k rK t } n t  |  } |  j j | |  |  j | j	 |  |  j
 | j	 |  ~ | t k	 r | |  j k r y t | |  j  } | | _ Wn t k
 r Yn X|  j j | |  ~ d |  j k rY|  j j rYy& |  j j |  d | d | d | Wn |  j | |    Yn Xt j r|  t k	 ry# t j |  d | d | d | Wn |  j | |    Yn X| S)aa  Connect *receiver* to signal events sent by *sender*.

        :param receiver: A callable.  Will be invoked by :meth:`send` with
          `sender=` as a single positional argument and any \*\*kwargs that
          were provided to a call to :meth:`send`.

        :param sender: Any object or :obj:`ANY`, defaults to ``ANY``.
          Restricts notifications delivered to *receiver* to only those
          :meth:`send` emissions sent by *sender*.  If ``ANY``, the receiver
          will always be notified.  A *receiver* may be connected to
          multiple *sender* values on the same Signal through multiple calls
          to :meth:`connect`.

        :param weak: If true, the Signal will hold a weakref to *receiver*
          and automatically disconnect when *receiver* goes out of scope or
          is garbage collected.  Defaults to True.

        r   receiversenderweakZreceiver_argZ
sender_argZweak_arg)r   r	   _cleanup_receiverreceiver_idr   ANY_IDr   
setdefaultr   addr   r   _cleanup_sender	sender_id	TypeError__dict__r   send
disconnect)r   r   r   r   r   receiver_refr#   
sender_refr   r   r   connect\   sP    	zSignal.connectFc                s       f d d   } | S)aK  Connect the decorated function as a receiver for *sender*.

        :param sender: Any object or :obj:`ANY`.  The decorated function
          will only receive :meth:`send` emissions sent by *sender*.  If
          ``ANY``, the receiver will always be notified.  A function may be
          decorated multiple times with differing *sender* values.

        :param weak: If true, the Signal will hold a weakref to the
          decorated function and automatically disconnect when *receiver*
          goes out of scope or is garbage collected.  Unlike
          :meth:`connect`, this defaults to False.

        The decorated function will be invoked by :meth:`send` with
          `sender=` as a single positional argument and any \*\*kwargs that
          were provided to the call to :meth:`send`.


        .. versionadded:: 1.1

        c                s     j  |     |  S)N)r*   )fn)r   r   r   r   r   	decorator   s    z%Signal.connect_via.<locals>.decoratorr   )r   r   r   r,   r   )r   r   r   r   connect_via   s    zSignal.connect_viac          	   c   sN   |  j  | d | d d y	 d VWn |  j |    Yn X|  j |  d S)a  Execute a block with the signal temporarily connected to *receiver*.

        :param receiver: a receiver callable
        :param sender: optional, a sender to filter on

        This is a context manager for use in the ``with`` statement.  It can
        be useful in unit tests.  *receiver* is connected to the signal for
        the duration of the ``with`` block, and will be disconnected
        automatically when exiting the block:

        .. testsetup::

          from __future__ import with_statement
          from blinker import Signal
          on_ready = Signal()
          receiver = lambda sender: None

        .. testcode::

          with on_ready.connected_to(receiver):
             # do stuff
             on_ready.send(123)

        .. versionadded:: 1.1

        r   r   FN)r*   r'   )r   r   r   r   r   r   connected_to   s    	zSignal.connected_toc             C   s   t  d t  |  j | |  S)a_  An alias for :meth:`connected_to`.

        :param receiver: a receiver callable
        :param sender: optional, a sender to filter on

        .. versionadded:: 0.9

        .. versionchanged:: 1.1
          Renamed to :meth:`connected_to`.  ``temporarily_connected_to``
          was deprecated in 1.2 and removed in a subsequent version.

        zAtemporarily_connected_to is deprecated; use connected_to instead.)r   DeprecationWarningr.   )r   r   r   r   r   r   temporarily_connected_to   s    zSignal.temporarily_connected_toc                s   t    d k r d  n5 t    d k rF t d t      n
  d  |  j s] g  S   f d d   |  j   D Sd S)a  Emit this signal on behalf of *sender*, passing on \*\*kwargs.

        Returns a list of 2-tuples, pairing receivers with their return
        value. The ordering of receiver notification is undefined.

        :param \*sender: Any object or ``None``.  If omitted, synonymous
          with ``None``.  Only accepts one positional argument.

        :param \*\*kwargs: Data to be sent to receivers.

        r   N   z5send() accepts only one positional argument, %s givenc                s%   g  |  ] } | |     f  q Sr   r   ).0r   )kwargsr   r   r   
<listcomp>
  s   	zSignal.send.<locals>.<listcomp>)lenr$   r   receivers_for)r   r   r3   r   )r3   r   r   r&      s    	
	zSignal.sendc             C   sA   |  j  s d S|  j t r d S| t k r. d St |  |  j k S)zTrue if there is probably a receiver for *sender*.

        Performs an optimistic check only.  Does not guarantee that all
        weakly referenced receivers are still alive.  See
        :meth:`receivers_for` for a stronger search.

        FT)r   r   r   r   r   )r   r   r   r   r   has_receivers_for  s    	zSignal.has_receivers_forc             c   s   |  j  r t |  } | |  j k r? |  j t |  j | B} n |  j t j   } xq | D]i } |  j  j |  } | d k r qY t | t  r |   } | d k r |  j | t  qY | } | VqY Wd S)z2Iterate all live receivers listening for *sender*.N)	r   r   r   r   copyget
isinstancer   _disconnect)r   r   r#   Zidsr   r   Zstrongr   r   r   r6     s"    	
	zSignal.receivers_forc             C   sx   | t  k r t } n t |  } t |  } |  j | |  d |  j k rt |  j j rt |  j j |  d | d | d S)a  Disconnect *receiver* from this signal's events.

        :param receiver: a previously :meth:`connected<connect>` callable

        :param sender: a specific sender to disconnect from, or :obj:`ANY`
          to disconnect from all senders.  Defaults to ``ANY``.

        r   r   r   N)r   r   r   r;   r%   r   r   r&   )r   r   r   r#   r   r   r   r   r'   3  s    		zSignal.disconnectc             C   sv   | t  k r^ |  j j | d  rH x$ |  j j   D] } | j |  q1 W|  j j | d   n |  j | j |  d  S)NF)r   r   popr   valuesdiscardr   )r   r   r#   Zbucketr   r   r   r;   I  s    zSignal._disconnectc             C   s   |  j  | j t  d S)z'Disconnect a receiver from all senders.N)r;   r   r   )r   r(   r   r   r   r   R  s    zSignal._cleanup_receiverc             C   sf   | j  } | t k s t  |  j j | d  x1 |  j j | f   D] } |  j | j |  qD Wd S)z'Disconnect all receivers from a sender.N)r#   r   AssertionErrorr   r<   r   r   r>   )r   r)   r#   r   r   r   r   r"   V  s
    	zSignal._cleanup_senderc             C   s8   |  j  j   |  j j   |  j j   |  j j   d S)z4Throw away all signal state.  Useful for unit tests.N)r   clearr   r   r   )r   r   r   r   _clear_state^  s    zSignal._clear_state)__name__
__module____qualname__r   r   r   r   r   r   r*   r-   r   r.   r0   r&   r7   r6   r'   r;   r   r"   rA   r   r   r   r   r      s$   D$	r   a  Sent by a :class:`Signal` after a receiver connects.

:argument: the Signal that was connected to
:keyword receiver_arg: the connected receiver
:keyword sender_arg: the sender to connect to
:keyword weak_arg: true if the connection to receiver_arg is a weak reference

.. deprecated:: 1.2

As of 1.2, individual signals have their own private
:attr:`~Signal.receiver_connected` and
:attr:`~Signal.receiver_disconnected` signals with a slightly simplified
call signature.  This global signal is planned to be removed in 1.6.

c               @   s1   e  Z d  Z d Z d d d  Z d d   Z d S)NamedSignalz%A named generic notification emitter.Nc             C   s   t  j |  |  | |  _ d  S)N)r   r   name)r   rF   r   r   r   r   r   {  s    zNamedSignal.__init__c             C   s*   t  j |   } d | d  d  |  j f S)Nz%s; %r>r1   )r   __repr__rF   )r   baser   r   r   rH     s    zNamedSignal.__repr__)rB   rC   rD   r   r   rH   r   r   r   r   rE   x  s   rE   c               @   s%   e  Z d  Z d Z d d d  Z d S)	Namespacez%A mapping of signal names to signals.Nc             C   s>   y |  | SWn+ t  k
 r9 |  j | t | |   SYn Xd S)zReturn the :class:`NamedSignal` *name*, creating it if required.

        Repeated calls to this function will return the same signal object.

        N)KeyErrorr    rE   )r   rF   r   r   r   r   signal  s    zNamespace.signal)rB   rC   rD   r   rL   r   r   r   r   rJ     s   rJ   c               @   s%   e  Z d  Z d Z d d d  Z d S)WeakNamespacea  A weak mapping of signal names to signals.

    Automatically cleans up unused Signals when the last reference goes out
    of scope.  This namespace implementation exists for a measure of legacy
    compatibility with Blinker <= 1.2, and may be dropped in the future.

    Nc             C   s>   y |  | SWn+ t  k
 r9 |  j | t | |   SYn Xd S)zReturn the :class:`NamedSignal` *name*, creating it if required.

        Repeated calls to this function will return the same signal object.

        N)rK   r    rE   )r   rF   r   r   r   r   rL     s    zWeakNamespace.signal)rB   rC   rD   r   rL   r   r   r   r   rM     s   rM   N)r   warningsr   weakrefr   Zblinker._utilitiesr   r   r   r   r   r	   r
   r   r   objectr   r   rE   dictrJ   rM   rL   r   r   r   r   <module>
   s   4	 I	