U
    .e)                  	   @  sJ  d Z ddlm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 d2ddZ!dd Z"d3d d!Z#d4d#d$Z$d5d'd(Z%d6d+d,Z&d7d.d/Z'd0d1 Z(eZ)eZ*dS )8zFunctional Utilities.    )annotationsN)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-48hrr5dg/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   aM  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   7   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__<   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   r4   A   s    zLRUCache.updateTc              
   C  s*   | j  | j|W  5 Q R  S Q R X d S r   )r-   r.   r7   )r   r3   r   r   r   r7   J   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*   r5   r.   r/   nextiterr0   r   r   r   __setitem__N   s    zLRUCache.__setitem__c                 C  s
   t | jS r   )r<   r.   r%   r   r   r   __iter__U   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_itemsX   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?   rA   r   r   r   _iterate_valuesa   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_keysk   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   r1   deltaZnewvalr   r   r   incrq   s    zLRUCache.incrc                 C  s   t t| }|d |S )Nr-   )dictvarsr/   )r   dr   r   r   __getstate__y   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   r2   r4   r7   r=   r>   rC   	iteritemsrD   
itervaluesrF   iterkeysrJ   rN   rQ   rE   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sortedrW   r@   misseshits)r8   r9   r1   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\   r[   r   )r]   r^   r   r   ra      s    z(memoize.<locals>._memoize.<locals>.clearr   )r+   Lockr   r\   r[   ra   Zoriginal_func)r_   ra   Cacher`   maxsize)r]   r^   r_   r-   r   _memoize   s    
zmemoize.<locals>._memoizer   )re   r`   rd   rf   r   rc   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_   r8   r9   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   rg   r%   r   r   r   rk      s    zlazy.evaluatec                 C  s
   t |  S r   )rH   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   rm   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)ri   rj   )	__class__rh   ri   rj   r%   r   r   r   
__reduce__   s    zlazy.__reduce__N)r'   r(   r)   rR   r   r    rk   rl   r&   ro   rp   rr   rt   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   rk   )r   r   r   r   r      s    
r   c                 C  s   t | |ot | |pd S )zwReturn true if the object is iterable.

    Note:
    ----
        Returns false if object is a mapping or string.
    r   )ru   )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   )rv   rw   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   .0rB   vr   r   r   
<dictcomp>   s       zdictfilter.<locals>.<dictcomp>)rK   rW   )rM   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   r:   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;   r6   rG   r	   abs)r_   Zcatchr8   r9   Zerrbackmax_retriesZinterval_startZinterval_stepZinterval_maxcallbacktimeoutZinterval_rangeendretriesexcZttsr:   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_reprrx   fmtr   r   	<genexpr>R  s     zreprkwargs.<locals>.<genexpr>)joinrW   )r9   sepr   r   r   r   
reprkwargsQ  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   )namer8   r9   r   r   r   r   reprcallU  s     r   c                 C  s   t | }||jkp||jkS r   )inspectgetfullargspecr8   
kwonlyargs)funcargument_nameZargument_specr   r   r   accepts_argument^  s    

r   )N)r   Nr   F)r   Nr   r   )	NNNNr   r   r   NN)r   r   )r   Nr   )+rR   
__future__r   r   r~   r+   collectionsr   r   collections.abcr   r   	itertoolsr   r   r
   r	   Z
vine.utilsr   encodingr   r   __all__objectrX   r   r   r   r   r   rH   r   r   r   r   r   r   r   r   r   r   ZpromiseZmaybe_promiser   r   r   r   <module>   sH   [%*



           
>

		