U
    dl)                  	   @   s>  d Z ddlZddlZddlZddlmZmZ ddlmZm	Z	 ddl
mZmZ ddlmZmZ ddlmZ dd	lmZ d
Ze ZG dd dZG dd deZddefddZG dd dZdd Ze	efeffddZe	effddZd1ddZdd Z d2dd Z!d3d"d#Z"d4d&d'Z#d5d*d+Z$d6d-d.Z%d/d0 Z&eZ'eZ(dS )7zFunctional Utilities.    N)OrderedDictUserDict)IterableMapping)countrepeat)sleeptime)wraps   )	safe_repr)LRUCachememoizelazymaybe_evaluateis_list
maybe_list
dictfilterretry_over_timec                   @   s$   e Zd Zdd Zdd Zdd ZdS )ChannelPromisec                 C   s
   || _ d S N)__contract__)selfZcontract r   :/tmp/pip-unpacked-wheel-hqfrjlvz/kombu/utils/functional.py__init__   s    zChannelPromise.__init__c                 C   s4   z| j W S  tk
r.   |   }| _ | Y S X d S r   )	__value__AttributeErrorr   )r   valuer   r   r   __call__   s
    zChannelPromise.__call__c                 C   s:   zt | jW S  tk
r4   dt| jdd Y S X d S )Nz<promise: 0xx>)reprr   r   idr   r   r   r   r   __repr__#   s    zChannelPromise.__repr__N)__name__
__module____qualname__r   r   r%   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdddZdd Zdd Zdd
dZdd Zdd Z	dd Z
e
Zdd ZeZdd ZeZdddZdd Zdd ZeZeZe
ZdS ) r   a?  LRU Cache implementation using a doubly linked list to track access.

    Arguments:
        limit (int): The maximum number of keys to keep in the cache.
            When a new key is inserted and the limit has been exceeded,
            the *Least Recently Used* key will be discarded from the
            cache.
    Nc                 C   s   || _ t | _t | _d S r   )limit	threadingRLockmutexr   data)r   r)   r   r   r   r   4   s    
zLRUCache.__init__c              
   C   s6   | j & | j| }| |< |W  5 Q R  S Q R X d S r   )r,   r-   popr   keyr   r   r   r   __getitem__9   s    zLRUCache.__getitem__c              	   O   sb   | j R | j| j }}|j|| |rTt||krTtt|| D ]}|jdd qBW 5 Q R X d S )NF)last)r,   r-   r)   updatelenrangepopitem)r   argskwargsr-   r)   _r   r   r   r3   >   s    zLRUCache.updateTc              
   C   s*   | j  | j|W  5 Q R  S Q R X d S r   )r,   r-   r6   )r   r2   r   r   r   r6   G   s    zLRUCache.popitemc              	   C   sL   | j < | jr4t| j| jkr4| jtt| j || j|< W 5 Q R X d S r   )r,   r)   r4   r-   r.   nextiterr/   r   r   r   __setitem__K   s    zLRUCache.__setitem__c                 C   s
   t | jS r   )r;   r-   r$   r   r   r   __iter__R   s    zLRUCache.__iter__c              
   c   sJ   | j : | D ].}z|| j| fV  W q tk
r8   Y qX qW 5 Q R X d S r   r,   r-   KeyErrorr   kr   r   r   _iterate_itemsU   s    zLRUCache._iterate_itemsc              
   c   sF   | j 6 | D ]*}z| j| V  W q tk
r4   Y qX qW 5 Q R X d S r   r>   r@   r   r   r   _iterate_values^   s    zLRUCache._iterate_valuesc              
   C   s(   | j  | j W  5 Q R  S Q R X d S r   )r,   r-   keysr$   r   r   r   _iterate_keysh   s    zLRUCache._iterate_keysr   c              
   C   sB   | j 2 t| j|| }t|| |< |W  5 Q R  S Q R X d S r   )r,   intr-   r.   str)r   r0   deltaZnewvalr   r   r   incrn   s    zLRUCache.incrc                 C   s   t t| }|d |S )Nr,   )dictvarsr.   )r   dr   r   r   __getstate__v   s    
zLRUCache.__getstate__c                 C   s   || _ t | _d S r   )__dict__r*   r+   r,   )r   stater   r   r   __setstate__{   s    zLRUCache.__setstate__)N)T)r   )r&   r'   r(   __doc__r   r1   r3   r6   r<   r=   rB   	iteritemsrC   
itervaluesrE   iterkeysrI   rM   rP   rD   valuesitemsr   r   r   r   r   *   s&   	
	

r   c                    s    fdd}|S )z)Decorator to cache function return value.c                    sX   t  dt fdd  fdd}d  _ _| _ _ S )N)r)   c                     s   r| |}n| t f tt|  }z | }W 5 Q R X W nD tk
r   | |}  jd7  _ ||< W 5 Q R X Y nX   jd7  _|S )Nr   )KEYWORD_MARKtuplesortedrV   r?   misseshits)r7   r8   r0   r   )_Mcachefunkeyfunr,   r   r   r\      s    
z%memoize.<locals>._memoize.<locals>._Mc                      s      d  _ _dS )z+Clear the cache and reset cache statistics.r   N)clearr[   rZ   r   )r\   r]   r   r   r`      s    z(memoize.<locals>._memoize.<locals>.clearr   )r*   Lockr
   r[   rZ   r`   Zoriginal_func)r^   r`   Cacher_   maxsize)r\   r]   r^   r,   r   _memoize   s    
zmemoize.<locals>._memoizer   )rd   r_   rc   re   r   rb   r   r      s     r   c                   @   sX   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdS )r   a
  Holds lazy evaluation.

    Evaluated when called or if the :meth:`evaluate` method is called.
    The function is re-evaluated on every call.

    Overloaded operations that will evaluate the promise:
        :meth:`__str__`, :meth:`__repr__`, :meth:`__cmp__`.
    c                 O   s   || _ || _|| _d S r   _fun_args_kwargs)r   r^   r7   r8   r   r   r   r      s    zlazy.__init__c                 C   s   |   S r   )evaluater$   r   r   r   r      s    zlazy.__call__c                 C   s   | j | j| jS r   rf   r$   r   r   r   rj      s    zlazy.evaluatec                 C   s
   t |  S r   )rG   r$   r   r   r   __str__   s    zlazy.__str__c                 C   s
   t |  S r   )r"   r$   r   r   r   r%      s    zlazy.__repr__c                 C   s
   |  |kS r   r   r   rhsr   r   r   __eq__   s    zlazy.__eq__c                 C   s
   |  |kS r   r   rl   r   r   r   __ne__   s    zlazy.__ne__c                 C   s   | |t | < | S r   )r#   )r   memor   r   r   __deepcopy__   s    zlazy.__deepcopy__c                 C   s   | j | jf| j| jdfS )N)rh   ri   )	__class__rg   rh   ri   r$   r   r   r   
__reduce__   s    zlazy.__reduce__N)r&   r'   r(   rQ   r   r   rj   rk   r%   rn   ro   rq   rs   r   r   r   r   r      s   	r   c                 C   s   t | tr|  S | S )z9Evaluate value only if value is a :class:`lazy` instance.)
isinstancer   rj   )r   r   r   r   r      s    
r   c                 C   s   t | |ot | |pd S )znReturn true if the object is iterable.

    Note:
        Returns false if object is a mapping or string.
    r   )rt   )objscalarsZitersr   r   r   r      s    r   c                 C   s   | dkst | |r| S | gS )z0Return list of one element if ``l`` is a scalar.N)r   )ru   rv   r   r   r   r      s    r   c                 K   s2   | dkr|n|rt | f|n| } dd |  D S )z=Remove all keys from dict ``d`` whose value is :const:`None`.Nc                 S   s   i | ]\}}|d k	r||qS r   r   .0rA   vr   r   r   
<dictcomp>   s       zdictfilter.<locals>.<dictcomp>)rJ   rV   )rL   kwr   r   r   r      s     r   c                 c   s2   t | } tj}td D ]}||  | d V  qd S )Nr   )listrandomshuffler   )itr~   r9   r   r   r   shufflecycle   s
    r         ?Fc                 c   s:   | d }|r||kr$|V  ||7 }q|s*q6|| V  qd S )Nr   r   )startstopstep
repeatlastcurr   r   r   fxrange   s    
r         Y@c                 c   sH   d| d  }}||krqD|V  |r2t || |}n||7 }||7 }qd S )Nr   r   )min)r   r   r   maxZsum_r   r   r   r   
fxrangemax  s    r         c                 C   s  |si n|}|sg n|}t ||| |dd}|
r:t |
 nd}t D ]}z| ||W   S  |k
r  } z|dk	r~||kr~ |rt |kr |	r|	  t|r||||nt|}|rtt|D ]}|	r|	  td qttt||  W 5 d}~X Y qDX qDdS )a  Retry the function over and over until max retries is exceeded.

    For each retry we sleep a for a while before we try again, this interval
    is increased for every retry until the max seconds is reached.

    Arguments:
        fun (Callable): The function to try
        catch (Tuple[BaseException]): Exceptions to catch, can be either
            tuple or a single exception class.

    Keyword Arguments:
        args (Tuple): Positional arguments passed on to the function.
        kwargs (Dict): Keyword arguments passed on to the function.
        errback (Callable): Callback for when an exception in ``catch``
            is raised.  The callback must take three arguments:
            ``exc``, ``interval_range`` and ``retries``, where ``exc``
            is the exception instance, ``interval_range`` is an iterator
            which return the time in seconds to sleep next, and ``retries``
            is the number of previous retries.
        max_retries (int): Maximum number of retries before we give up.
            If neither of this and timeout is set, we will retry forever.
            If one of this and timeout is reached, stop.
        interval_start (float): How long (in seconds) we start sleeping
            between retries.
        interval_step (float): By how much the interval is increased for
            each retry.
        interval_max (float): Maximum number of seconds to sleep
            between retries.
        timeout (int): Maximum seconds waiting before we give up.
    T)r   Nr   )	r   r	   r   floatr:   r5   rF   r   abs)r^   Zcatchr7   r8   Zerrbackmax_retriesZinterval_startZinterval_stepZinterval_maxcallbacktimeoutZinterval_rangeendretriesexcZttsr9   r   r   r   r     s6    ! 

r   , {0}={1}c                    s   |  fdd|  D S )Nc                 3   s"   | ]\}}  |t|V  qd S r   )format
_safe_reprrw   fmtr   r   	<genexpr>L  s     zreprkwargs.<locals>.<genexpr>)joinrV   )r8   sepr   r   r   r   
reprkwargsK  s    r   r   c                 C   s>   |si n|}d | |tt|p d|r0|r0|p2dt||S )Nz
{}({}{}{})r    )r   r   mapr   r   )namer7   r8   r   r   r   r   reprcallO  s     r   c                 C   s   t | }||jkp||jkS r   )inspectgetfullargspecr7   
kwonlyargs)funcargument_nameZargument_specr   r   r   accepts_argumentX  s    

r   )N)r   Nr   F)r   Nr   r   )	NNNNr   r   r   NN)r   r   )r   Nr   ))rQ   r   r}   r*   collectionsr   r   collections.abcr   r   	itertoolsr   r   r	   r   Z
vine.utilsr
   encodingr   r   __all__objectrW   r   r   r   r   r   rG   r   r   r   r   r   r   r   r   r   r   ZpromiseZmaybe_promiser   r   r   r   <module>   sF   Z%*	


           
<

		