U
    {h                     @   s8   d Z dgZG dd dZG dd dZG dd dZdS )a  
Helper for looping over sequences, particular in templates.

Often in a loop in a template it's handy to know what's next up,
previously up, if this is the first or last item in the sequence, etc.
These can be awkward to manage in a normal Python loop, but using the
looper you can get a better sense of the context.  Use like::

    >>> for loop, item in looper(['a', 'b', 'c']):
    ...     print loop.number, item
    ...     if not loop.last:
    ...         print '---'
    1 a
    ---
    2 b
    ---
    3 c

looperc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   z
    Helper for looping (particularly in templates)

    Use this like::

        for loop, item in looper(seq):
            if loop.first:
                ...
    c                 C   s
   || _ d S N)seqselfr    r   :/tmp/pip-unpacked-wheel-fhl22ezh/Cython/Tempita/_looper.py__init__#   s    zlooper.__init__c                 C   s
   t | jS r   )looper_iterr   r   r   r   r   __iter__&   s    zlooper.__iter__c                 C   s   d| j j| jf S )Nz<%s for %r>)	__class____name__r   r
   r   r   r   __repr__)   s     zlooper.__repr__N)r   
__module____qualname____doc__r   r   r   r   r   r   r   r      s   
c                   @   s$   e Zd Zdd Zdd Zdd ZdS )r	   c                 C   s   t || _d| _d S N    )listr   posr   r   r   r   r   0   s    
zlooper_iter.__init__c                 C   s   | S r   r   r
   r   r   r   r   4   s    zlooper_iter.__iter__c                 C   s@   | j t| jkrtt| j| j | j| j  f}|  j d7  _ |S N   )r   lenr   StopIterationloop_pos)r   resultr   r   r   __next__7   s
    zlooper_iter.__next__N)r   r   r   r   r   r   r   r   r   r   r	   .   s   r	   c                   @   s   e Zd Zdd Zdd Zdd ZeeZdd ZeeZd	d
 ZeeZdd Z	ee	Z	dd Z
ee
Z
dd ZeeZdd ZeeZdd ZeeZdd ZeeZdd ZeeZd ddZd!ddZdd ZdS )"r   c                 C   s   || _ || _d S r   r   r   )r   r   r   r   r   r   r   A   s    zloop_pos.__init__c                 C   s   d| j | j | jf S )Nz<loop pos=%r at %r>r   r
   r   r   r   r   E   s    
 zloop_pos.__repr__c                 C   s   | j S r   r   r
   r   r   r   indexI   s    zloop_pos.indexc                 C   s
   | j d S r   r   r
   r   r   r   numberM   s    zloop_pos.numberc                 C   s   | j | j S r   r   r
   r   r   r   itemQ   s    zloop_pos.itemc                 C   s.   z| j | jd  W S  tk
r(   Y d S X d S r   )r   r   
IndexErrorr
   r   r   r   r   U   s    zloop_pos.__next__c                 C   s   | j dkrd S | j| j d  S )Nr   r   )r   r   r
   r   r   r   previous\   s    
zloop_pos.previousc                 C   s   | j d  S N   r   r
   r   r   r   oddb   s    zloop_pos.oddc                 C   s
   | j d S r$   r   r
   r   r   r   evenf   s    zloop_pos.evenc                 C   s
   | j dkS r   r   r
   r   r   r   firstj   s    zloop_pos.firstc                 C   s   | j t| jd kS r   )r   r   r   r
   r   r   r   lastn   s    zloop_pos.lastc                 C   s
   t | jS r   )r   r   r
   r   r   r   lengthr   s    zloop_pos.lengthNc                 C   s   | j r
dS | | j| j|S )a  
        Returns true if this item is the start of a new group,
        where groups mean that some attribute has changed.  The getter
        can be None (the item itself changes), an attribute name like
        ``'.attr'``, a function, or a dict key or list index.
        T)r(   _compare_groupr!   r#   r   getterr   r   r   first_groupv   s    zloop_pos.first_groupc                 C   s   | j r
dS | | j| j|S )a  
        Returns true if this item is the end of a new group,
        where groups mean that some attribute has changed.  The getter
        can be None (the item itself changes), an attribute name like
        ``'.attr'``, a function, or a dict key or list index.
        T)r)   r+   r!   r   r,   r   r   r   
last_group   s    zloop_pos.last_groupc                 C   s   |d kr||kS t |trt|drt|dd  }|dr^|d d }t|| t|| kS t||t||kS n*t|dr||||kS || || kS d S )N.r   z()__call__)
isinstancestr
startswithendswithgetattrhasattr)r   r!   otherr-   r   r   r   r+      s    


zloop_pos._compare_group)N)N)r   r   r   r   r   r   propertyr    r!   r   r#   r&   r'   r(   r)   r*   r.   r/   r+   r   r   r   r   r   ?   s2   

r   N)r   __all__r   r	   r   r   r   r   r   <module>   s   