U
    lª/eé	  ã                   @   sÂ   d dl Z d dlmZmZmZmZ d dlmZ ddlm	Z	 ddl
mZ ddlmZmZ edƒZeee ee d	œd
d„Zee eeee  dœdd„Zee ee eee ee f dœdd„ZdS )é    N)ÚAsyncIterableÚListÚTupleÚTypeVar)Úmaybe_awaité   )Úiter)Úislice)ÚAnyIterableÚ	PredicateÚT)ÚnÚiterableÚreturnc                 Ã   s*   | dk rt dƒ‚dd„ t|| ƒ2 ƒI dH S )a	  
    Return the first n items of iterable as a list.

    If there are too few items in iterable, all of them are returned.
    n needs to be at least 0. If it is 0, an empty list is returned.

    Example::

        first_two = await take(2, [1, 2, 3, 4, 5])

    r   z(take's first parameter can't be negativec                 Ó   s   g | z3 d H W }|‘q6 S ©N© )Ú.0Úitemr   r   ú?/tmp/pip-unpacked-wheel-n_uj7zou/aioitertools/more_itertools.pyÚ
<listcomp>   s     ztake.<locals>.<listcomp>N)Ú
ValueErrorr	   )r   r   r   r   r   Útake   s    r   )r   r   r   c                 C  s<   t | ƒ}t||ƒI dH }|g kr8|V  t||ƒI dH }qdS )a#  
    Break iterable into chunks of length n.

    The last chunk will be shorter if the total number of items is not
    divisible by n.

    Example::

        async for chunk in chunked([1, 2, 3, 4, 5], n=2):
            ...  # first iteration: chunk == [1, 2]; last one: chunk == [5]
    N)r   r   )r   r   ÚitÚchunkr   r   r   Úchunked"   s
    r   )Ú	predicater   r   c                 ƒ   s>   t |ƒ‰ t ¡  ¡ ‰‡ ‡‡fdd„}‡ ‡fdd„}|ƒ |ƒ fS )aï  
    A variant of :func:`aioitertools.takewhile` that allows complete access to the
    remainder of the iterator.

         >>> it = iter('ABCdEfGhI')
         >>> all_upper, remainder = await before_and_after(str.isupper, it)
         >>> ''.join([char async for char in all_upper])
         'ABC'
         >>> ''.join([char async for char in remainder])
         'dEfGhI'

    Note that the first iterator must be fully consumed before the second
    iterator can generate valid results.
    c                    sL   ˆ 2 z63 d H W } t ˆ| ƒƒI d H r*| V  qˆ | ¡  d S q6 ˆ t¡ d S r   )r   Z
set_resultZset_exceptionÚStopAsyncIteration)Úelem©r   r   Ú
transitionr   r   Útrue_iteratorK   s    

z'before_and_after.<locals>.true_iteratorc                    sF   zˆI d H V  W n t k
r&   Y d S X ˆ 2 z3 d H W } | V  q,6 d S r   )r   )Úelm)r   r   r   r   Úremainder_iteratorU   s    z,before_and_after.<locals>.remainder_iterator)r   ÚasyncioZget_event_loopZcreate_future)r   r   r    r"   r   r   r   Úbefore_and_after5   s
    
	r$   )r#   Útypingr   r   r   r   Zaioitertools.helpersr   Úbuiltinsr   Ú	itertoolsr	   Útypesr
   r   r   Úintr   r   r$   r   r   r   r   Ú<module>   s    þ