U
    .e.                     @   s  d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	 ddl
mZmZ ddlmZmZmZmZmZmZmZ ddlmZ dd	lmZ eeZd
ZdZG dd dZG dd deZdd Zdd Z dd Z!dd Z"d>ddZ#dd Z$d?ddZ%dd Z&d d! Z'd"d# Z(d$d% Z)G d&d' d'ee*Z+d@d)d*Z,dAed,ef e-e.d-d.d/Z/d0d1 Z0dBd2d3Z1d4d5 Z2d6d7 Z3d8d9 Z4d:d; Z5d<d= Z6dS )CzFunctional-style utilities.    N)UserList)partial)isliceteezip_longest)AnyCallable)LRUCache
dictfilteris_listlazymaybe_evaluate
maybe_listmemoize)promise)
get_logger)r	   r   r   r   mlazynoopfirstfirstmethodchunkspadlistmattrgetteruniqregenr
   r   r   head_from_funmaybefun_accepts_kwargsz4
def {fun_name}({fun_args}):
    return {fun_value}
c                   @   s   e Zd Zdd Zdd ZdS )DummyContextc                 C   s   | S N selfr    r    ;/tmp/pip-unpacked-wheel-f4liivr4/celery/utils/functional.py	__enter__   s    zDummyContext.__enter__c                 G   s   d S r   r    )r"   exc_infor    r    r#   __exit__!   s    zDummyContext.__exit__N)__name__
__module____qualname__r$   r&   r    r    r    r#   r      s   r   c                       s(   e Zd ZdZdZdZ fddZ  ZS )r   zMemoized lazy evaluation.

    The function is only evaluated once, every subsequent access
    will return the same value.
    FNc                    s   | j st  | _d| _ | jS NT)	evaluatedsuperevaluate_valuer!   	__class__r    r#   r-   0   s    zmlazy.evaluate)r'   r(   r)   __doc__r+   r.   r-   __classcell__r    r    r/   r#   r   %   s   r   c                  O   s   dS )zONo operation.

    Takes any arguments/keyword arguments and does nothing.
    Nr    )argskwargsr    r    r#   r   7   s    r   c                 O   s   | S )z%Return the first positional argument.r    )argr3   r4   r    r    r#   pass1>   s    r6   c                 c   s$   | D ]}t |tr| }|V  qd S r   )
isinstancer   )itvaluer    r    r#   evaluate_promisesC   s    
r:   c                    s   t  fddt|D dS )zReturn the first element in ``it`` that ``predicate`` accepts.

    If ``predicate`` is None it will return the first item that's not
    :const:`None`.
    c                 3   s,   | ]$} d k	r |rn|d k	r|V  qd S r   r    ).0v	predicater    r#   	<genexpr>Q   s
     
 zfirst.<locals>.<genexpr>N)nextr:   )r>   r8   r    r=   r#   r   J   s    r   c                    s    fdd}|S )zMultiple dispatch.

    Return a function that with a list of instances,
    finds the first instance that gives a value for the given method.

    The list can also contain lazy instances
    (:class:`~kombu.utils.functional.lazy`.)
    c              	      sd   | D ]Z}z0t t| }r,|f||n|||}W n tk
rL   Y qX |d k	r|  S qd S r   )getattrr   AttributeError)r8   r3   r4   objmethZreplymethodon_callr    r#   _matchera   s    zfirstmethod.<locals>._matcherr    )rF   rG   rH   r    rE   r#   r   W   s    
r   c                 c   s(   | D ]}|gt t| |d  V  qdS )as  Split an iterator into chunks with `n` elements each.

    Warning:
        ``it`` must be an actual iterator, if you pass this a
        concrete sequence will get you repeating elements.

        So ``chunks(iter(range(1000)), 10)`` is fine, but
        ``chunks(range(1000), 10)`` is not.

    Example:
        # n == 2
        >>> x = chunks(iter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 2)
        >>> list(x)
        [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10]]

        # n == 3
        >>> x = chunks(iter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 3)
        >>> list(x)
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
       N)listr   )r8   nitemr    r    r#   r   p   s    r   c                 C   s"   t | d| |g|t|    S )a  Pad list with default elements.

    Example:
        >>> first, last, city = padlist(['George', 'Costanza', 'NYC'], 3)
        ('George', 'Costanza', 'NYC')
        >>> first, last, city = padlist(['George', 'Costanza'], 3)
        ('George', 'Costanza', None)
        >>> first, last, city, planet = padlist(
        ...     ['George', 'Costanza', 'NYC'], 4, default='Earth',
        ... )
        ('George', 'Costanza', 'NYC', 'Earth')
    N)rJ   len)	containersizedefaultr    r    r#   r      s    r   c                     s    fddS )zGet attributes, ignoring attribute errors.

    Like :func:`operator.itemgetter` but return :const:`None` on missing
    attributes instead of raising :exc:`AttributeError`.
    c                    s    fddD S )Nc                    s   i | ]}|t  |d qS r   )rA   )r;   attrrC   r    r#   
<dictcomp>   s      z1mattrgetter.<locals>.<lambda>.<locals>.<dictcomp>r    rR   attrsrR   r#   <lambda>       zmattrgetter.<locals>.<lambda>r    rT   r    rT   r#   r      s    r   c                    s   t    fdd| D S )z7Return all unique elements in ``it``, preserving order.c                 3   s$   | ]}| kr  |p|V  qd S r   )add)r;   rC   seenr    r#   r?      s      zuniq.<locals>.<genexpr>)setr8   r    rY   r#   r      s    r   c                 C   s    t | \}}t|d t||S )zYield pairs of (current, next) items in `it`.

    `next` is None if `current` is the last item.
    Example:
        >>> list(lookahead(x for x in range(6)))
        [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, None)]
    N)r   r@   r   )r8   abr    r    r#   	lookahead   s    
r_   c                 C   s   t | ttfr| S t| S )zConvert iterator to an object that can be consumed multiple times.

    ``Regen`` takes any iterable, and if the object is an
    generator it will cache the evaluated list on first access,
    so that the generator can be "consumed" multiple times.
    )r7   rJ   tuple_regenr\   r    r    r#   r      s    r   c                   @   sb   e Zd Zdd Zdd Zdd Zdd Zdd
dZdd Zdd Z	dd Z
edd Zdd Zd	S )ra   c                 C   s   || _ g | _d| _d S )NF)
_regen__it_regen__consumed_regen__done)r"   r8   r    r    r#   __init__   s    z_regen.__init__c                 C   s   t | jffS r   )rJ   datar!   r    r    r#   
__reduce__   s    z_regen.__reduce__c                    s(    fdd| j D | _ t | j| _d S )Nc                    s   g | ]} |qS r    r    )r;   elfuncr    r#   
<listcomp>   s     z_regen.map.<locals>.<listcomp>)rc   maprb   )r"   rj   r    ri   r#   rl      s    z
_regen.mapc                 C   s
   | j  S r   )rb   __length_hint__r!   r    r    r#   rm      s    z_regen.__length_hint__Nc                 c   s   | j s|d ks|dkrt| j}zt|}W n tk
rB   Y d S X | j| | j sz@zt|}| j| W n" tk
r   d| _ Y W qY nX W 5 |V  X |}|d k	rP|d8 }|dkrPqqPd S )Nr   TrI   )rd   iterrb   r@   StopIterationrc   append)r"   limitr8   nowZnext_r    r    r#   Z__lookahead_consume   s(    
z_regen.__lookahead_consumec                 c   s   | j E d H  |  E d H  d S r   )rc   _regen__lookahead_consumer!   r    r    r#   __iter__   s    z_regen.__iter__c                 C   s@   |dk r| j | S |t| j d }| j|dD ]}q0| j| S )Nr   rI   )rq   )rf   rM   rc   rs   )r"   indexZconsume_count_r    r    r#   __getitem__   s    
z_regen.__getitem__c                 C   s>   t | jrdS ztt|  W n tk
r4   Y dS X dS d S )NTF)rM   rc   r@   rn   ro   r!   r    r    r#   __bool__   s    
z_regen.__bool__c                 C   s    | j s| j| j d| _ | jS r*   )rd   rc   extendrb   r!   r    r    r#   rf   	  s    z_regen.datac                 C   s.   d | jjddd | jD | js(dndS )Nz<{}: [{}{}]>, c                 s   s   | ]}t |V  qd S r   )repr)r;   er    r    r#   r?     s     z"_regen.__repr__.<locals>.<genexpr>z... )formatr0   r'   joinrc   rd   r!   r    r    r#   __repr__  s
    z_regen.__repr__)N)r'   r(   r)   re   rg   rl   rm   rs   rt   rw   rx   propertyrf   r   r    r    r    r#   ra      s   


ra   Tc           
      C   sP  | j rXt| j }|r&ttt| j n| j }| jd |  }tt| j| d  |}n| jg  }}| j}| j}| jrt	| j
t	| j  }|rdd t| j D }	qt| j }	n| j
g  }}	dtd d|ddd |D |rd| nd |s|	r|sdnd |r"d|nd ddd |	D |rFd| nd gS )	Nc                 S   s   g | ]\}}||fqS r    r    )r;   ikwr    r    r#   rk   '  s    z!_argsfromspec.<locals>.<listcomp>rz   c                 s   s    | ]\}}| d | V  qdS )=Nr    r;   kr<   r    r    r#   r?   1  s     z _argsfromspec.<locals>.<genexpr>*c                 s   s"   | ]\}}| d | dV  qdS )z=""Nr    r   r    r    r#   r?   5  s     z**)defaultsrM   rJ   ranger3   zipvarargsvarkwkwonlydefaultsr[   
kwonlyargskeys	enumerateitemsr   filter)
specZreplace_defaultssplitr   
positionaloptionalr   r   r   Zkwonlyargs_optionalr    r    r#   _argsfromspec  s6    
r   F.)funboundreturnc           
      C   s   t | }t| }| jjdk}t | }|sJ|rJ|sJ|sJ| jj| j }} n| j}tj|t	t 
| dd}t| d| ji}t|| || }	||	_|rt|	t S |	S )z1Generate signature function from actual function.Zcython_function_or_methodrI   )Zfun_nameZfun_argsZ	fun_valuer'   )inspect
isfunctioncallabler0   r'   ismethod__call__FUNHEAD_TEMPLATEr~   r   getfullargspecloggerdebugr(   exec_sourcer   object)
r   r   Zis_functionZis_callableZ	is_cythonZ	is_methodnameZ
definition	namespaceresultr    r    r#   r   :  s(    




r   c                 C   s   t | }|jpt|j|kS r   )r   r   r   rM   r3   )r   rK   Zargspecr    r    r#   arity_greater[  s    
r   c                 C   s2   t |}|jp0|jp0|r(t|j|kS | |jkS r   )r   r   r   r   rM   r3   )r   r   positionr   r    r    r#   fun_takes_argument`  s    
r   c                 C   s   t dd t| j D S )z<Return true if function accepts arbitrary keyword arguments.c                 s   s   | ]}|j |jkr|V  qd S r   )kindVAR_KEYWORD)r;   pr    r    r#   r?   j  s   z%fun_accepts_kwargs.<locals>.<genexpr>)anyr   	signature
parametersvalues)r   r    r    r#   r   h  s    r   c                 C   s   |dk	r| |S |S )z$Call typ on value if val is defined.Nr    )typvalr    r    r#   r   p  s    r   c                 C   s   t | tr| |f S | |g S )zReturn copy of sequence seq with item added.

    Returns:
        Sequence: if seq is a tuple, the result will be a tuple,
           otherwise it depends on the implementation of ``__add__``.
    )r7   r`   )seqrL   r    r    r#   seq_concat_itemu  s    r   c                 C   s@   t t| |gtd}t| |s&|| } t||s8||}| | S )a  Concatenate two sequences: ``a + b``.

    Returns:
        Sequence: The return value will depend on the largest sequence
            - if b is larger and is a tuple, the return value will be a tuple.
            - if a is larger and is a list, the return value will be a list,
    )key)typemaxrM   r7   )r]   r^   Zpreferr    r    r#   seq_concat_seq  s    	

r   c                 C   s   t | ttfot | t S r   )r7   intfloatbool)r9   r    r    r#   is_numeric_value  s    r   )N)N)T)F)N)7r1   r   collectionsr   	functoolsr   	itertoolsr   r   r   typingr   r   Zkombu.utils.functionalr	   r
   r   r   r   r   r   Zviner   Zcelery.utils.logr   r'   r   __all__r   r   r   r   r6   r:   r   r   r   r   r   r   r_   r   rJ   ra   r   r   strr   r   r   r   r   r   r   r   r    r    r    r#   <module>   sD   $	

	W
"!

