o
    ;DitY                     @   s  d dl mZmZmZ d dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZ d dl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 m!Z!m"Z"m#Z# d dl$m%Z% d dl&m'Z' G d	d
 d
e(Z)G dd de)Z*dd Z+e+e*_+G dd de)Z,dd Z-G dd de*Z.e.Z/dd Z0dd Z1dd Z2dd Z3e3e*_3dd Z4e4e*_4dd  Z5e5e*_5G d!d" d"e*Z6d#d$ Z7d%d& Z8e8e*_8G d'd( d(e)Z9d)d* Z:dOd+d,Z;d-d. Z<e<e*_<G d/d0 d0e)Z=d1d2 Z>dOd3d4Z?G d5d6 d6e@ZAd7d8 ZBeBe*_BG d9d: d:e)ZCd;d< ZDdaEdaFdaGdPd>d?ZHG d@dA dAe(ZIdBdC ZJdDdE ZKdOdFdGZLeLe*_LdQdIdJZMdKdL ZNG dMdN dNe*ZOdS )R    )absolute_importdivisionprint_functionN)islicechaincycleproductpermutationscombinations	takewhile	dropwhilestarmapgroupbytee)Counter
namedtupleOrderedDict)compresscombinations_with_replacement)
imapizipizip_longestifilterifilterfalsereducenextstring_types	text_typePY3)FieldSelectionError)comparable_itemgetterc                   @   sf  e 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d Zdd Zdd Zdd ZdYd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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$dFdG Z%dHdI Z&dJdK Z'dLdM Z(dNdO Z)dPdQ Z*dRdS Z+dTdU Z,dVdW Z-dXS )ZIterContainerc                 C   s   | D ]	}||kr dS qdS )NTF )selfitemor"   r"   G/var/www/Datamplify/venv/lib/python3.10/site-packages/petl/util/base.py__contains__   s
   zIterContainer.__contains__c                 C   s   t dd | D S )Nc                 s   s    | ]}d V  qdS )   Nr"   ).0_r"   r"   r&   	<genexpr>   s    z(IterContainer.__len__.<locals>.<genexpr>sumr#   r"   r"   r&   __len__      zIterContainer.__len__c                 C   sZ   t |trztt| ||d W S  ty   tdw t |tr+t| |j|j|j	S d S )Nr(   zindex out of range)

isinstanceintr   r   StopIteration
IndexErrorslicestartstopstepr#   r$   r"   r"   r&   __getitem__   s   

zIterContainer.__getitem__c                 C   s   t N)NotImplementedErrorr.   r"   r"   r&   __iter__'   s   zIterContainer.__iter__c                 C   s.   t | D ]\}}||kr|  S qtd| )Nz%s is not in container)	enumerate
ValueError)r#   r$   ir%   r"   r"   r&   index*   s
   zIterContainer.indexc                 K      t | fi |S r;   )minr#   kwargsr"   r"   r&   rC   0      zIterContainer.minc                 K   rB   r;   )maxrD   r"   r"   r&   rG   3   rF   zIterContainer.maxc                 C      t | S r;   )lenr.   r"   r"   r&   rI   6      zIterContainer.lenc                 C   rH   r;   )setr.   r"   r"   r&   rK   9   rJ   zIterContainer.setc                 C   rH   r;   )	frozensetr.   r"   r"   r&   rL   <   rJ   zIterContainer.frozensetc                 C      t t| S r;   )listiterr.   r"   r"   r&   rN   ?      zIterContainer.listc                 C   rM   r;   )tuplerO   r.   r"   r"   r&   rQ   C   rP   zIterContainer.tuplec                 K   rB   r;   )dictrD   r"   r"   r&   rR   G   rF   zIterContainer.dictr   c                 C   
   t | |S r;   )r>   )r#   r6   r"   r"   r&   r>   J      
zIterContainer.enumeratec                 C   
   t || S r;   )filterr#   functionr"   r"   r&   rV   M   rT   zIterContainer.filterc                 C   rU   r;   )maprW   r"   r"   r&   rY   P   rT   zIterContainer.mapc                 K   s   t || fi |S r;   )r   )r#   rX   rE   r"   r"   r&   r   S   r0   zIterContainer.reducec                 O      t | g|R i |S r;   r,   r#   argsrE   r"   r"   r&   r-   V      zIterContainer.sumc                 C   rH   r;   )allr.   r"   r"   r&   r^   Y   rJ   zIterContainer.allc                 C   rH   r;   )anyr.   r"   r"   r&   r_   \   rJ   zIterContainer.anyc                 C   s   | D ]}|| qd S r;   r"   )r#   rX   r$   r"   r"   r&   apply_   s   
zIterContainer.applyc                 C   rH   r;   )r   r.   r"   r"   r&   counterc   rJ   zIterContainer.counterc                 C   rH   r;   )r   r.   r"   r"   r&   ordereddictf   rJ   zIterContainer.ordereddictc                 C   rH   r;   )r   r.   r"   r"   r&   r   i   rJ   zIterContainer.cyclec                 G      t | g|R  S r;   r   )r#   othersr"   r"   r&   r   l   rF   zIterContainer.chainc                 C   rU   r;   )r   r#   	predicater"   r"   r&   r   o   rT   zIterContainer.dropwhilec                 C   rU   r;   )r   rf   r"   r"   r&   r   r   rT   zIterContainer.takewhilec                 C   rU   r;   )r   rf   r"   r"   r&   r   u   rT   zIterContainer.ifilterc                 C   rU   r;   )r   rf   r"   r"   r&   r   x   rT   zIterContainer.ifilterfalsec                 C   rU   r;   )r   rW   r"   r"   r&   r   {   rT   zIterContainer.imapc                 C   rU   r;   )r   rW   r"   r"   r&   r   ~   rT   zIterContainer.starmapc                 G   rc   r;   r   )r#   r\   r"   r"   r&   r      rF   zIterContainer.islicec                 C   rS   r;   )r   )r#   	selectorsr"   r"   r&   r      rT   zIterContainer.compressc                 O   rZ   r;   )r   r[   r"   r"   r&   r      r]   zIterContainer.groupbyc                 O   rZ   r;   )r   r[   r"   r"   r&   r      r]   zIterContainer.teec                 O   rZ   r;   )r	   r[   r"   r"   r&   r	      r]   zIterContainer.permutationsc                 O   rZ   r;   )r
   r[   r"   r"   r&   r
      r]   zIterContainer.combinationsc                 O   rZ   r;   )r   r[   r"   r"   r&   r      r]   z+IterContainer.combinations_with_replacementc                 O   rZ   r;   )r   r[   r"   r"   r&   r      r]   zIterContainer.izipc                 O   rZ   r;   )r   r[   r"   r"   r&   r      r]   zIterContainer.izip_longestc                 O   rZ   r;   )r   r[   r"   r"   r&   r      r]   zIterContainer.productc                 C   rS   r;   rd   r#   otherr"   r"   r&   __add__   rT   zIterContainer.__add__c                 C   rS   r;   rd   rj   r"   r"   r&   __iadd__   rT   zIterContainer.__iadd__N)r   ).__name__
__module____qualname__r'   r/   r:   r=   rA   rC   rG   rI   rK   rL   rN   rQ   rR   r>   rV   rY   r   r-   r^   r_   r`   ra   rb   r   r   r   r   r   r   r   r   r   r   r   r   r	   r
   r   r   r   r   rl   rm   r"   r"   r"   r&   r!      sX    	
r!   c                       s   e Zd Z fddZ  ZS )Tablec                    s$   t |tr
t| |S tt| |S r;   )r1   r   
ValuesViewsuperrq   r:   r9   	__class__r"   r&   r:      s   

zTable.__getitem__)rn   ro   rp   r:   __classcell__r"   r"   rt   r&   rq      s    rq   c                 O   rZ   )a  
    Return a container supporting iteration over values in a given field or
    fields. E.g.::

        >>> import petl as etl
        >>> table1 = [['foo', 'bar'],
        ...           ['a', True],
        ...           ['b'],
        ...           ['b', True],
        ...           ['c', False]]
        >>> foo = etl.values(table1, 'foo')
        >>> foo
        foo: 'a', 'b', 'b', 'c'
        >>> list(foo)
        ['a', 'b', 'b', 'c']
        >>> bar = etl.values(table1, 'bar')
        >>> bar
        bar: True, None, True, False
        >>> list(bar)
        [True, None, True, False]
        >>> # values from multiple fields
        ... table2 = [['foo', 'bar', 'baz'],
        ...           [1, 'a', True],
        ...           [2, 'bb', True],
        ...           [3, 'd', False]]
        >>> foobaz = etl.values(table2, 'foo', 'baz')
        >>> foobaz
        ('foo', 'baz'): (1, True), (2, True), (3, False)
        >>> list(foobaz)
        [(1, True), (2, True), (3, False)]

    The field argument can be a single field name or index (starting from
    zero) or a tuple of field names and/or indexes. Multiple fields can also be
    provided as positional arguments.

    If rows are uneven, the value of the keyword argument `missing` is returned.

    )rr   )tablefieldrE   r"   r"   r&   values   s   (ry   c                   @   $   e Zd Zdd Zdd Zdd ZdS )rr   c                 O   s*   || _ t|dkr|d }|| _|| _d S )Nr(   r   )rw   rI   rx   rE   )r#   rw   rx   rE   r"   r"   r&   __init__   s
   
zValuesView.__init__c                 C   s   t | j| jfi | jS r;   )
itervaluesrw   rx   rE   r.   r"   r"   r&   r=      s   zValuesView.__iter__c                 C   sP   t ttt| d}t| jd }|d|d d 7 }t|dkr&|d7 }|S )N   z: z,    z, ...)rN   rY   reprr   r   rx   joinrI   r#   vreprsrr"   r"   r&   __repr__   s   zValuesView.__repr__Nrn   ro   rp   r{   r=   r   r"   r"   r"   r&   rr      s    rr   c              	   k   s    | dd }t| }zt|}W n ty   g }Y nw t||}t|dks,J dtj| }|D ]>}z	||}	|	V  W q3 tyq   t|dkrlt	 }	|D ]}
|
t|k r`|	
||
  qP|	
| qPt|	V  n|V  Y q3w d S )Nmissingr   zno field selectedr(   )getrO   r   r3   	asindicesrI   operator
itemgetterr4   rN   appendrQ   )rw   rx   rE   r   ithdrindicesgetvaluerowvaluer@   r"   r"   r&   r|      s6   


r|   c                   @      e Zd Zdd Zdd ZdS )TableWrapperc                 C   s
   || _ d S r;   inner)r#   r   r"   r"   r&   r{     rT   zTableWrapper.__init__c                 C   s
   t | jS r;   )rO   r   r.   r"   r"   r&   r=     rT   zTableWrapper.__iter__Nrn   ro   rp   r{   r=   r"   r"   r"   r&   r     s    r   c                 C   s   t tt| }t  }t|t tfs|f}|D ])}t|tr)|t| k r)|| q||v r<||}|| d||< qt	||S )z<Convert the given field `spec` into a list of field indices.N)
rN   rY   r   r1   rQ   r2   rI   r   rA   r   )r   specfldsr   sidxr"   r"   r&   r     s   


r   c                 C   s   t | |}t| }|S r;   )r   r    )r   r   r   getterr"   r"   r&   rowitemgetter2  s   
r   c                     s>   t | dkr
dd S t | dkr| d   fddS tj|  S )Nr   c                 S      t  S r;   rQ   r   r"   r"   r&   <lambda>:  s    zrowgetter.<locals>.<lambda>r(   c                    s
   |   fS r;   r"   r   rA   r"   r&   r   @  s   
 )rI   r   r   )r   r"   r   r&   	rowgetter8  s   
r   c                 C   s   t | }tt|S )a<  
    Return the header row for the given table. E.g.::

        >>> import petl as etl
        >>> table = [['foo', 'bar'], ['a', 1], ['b', 2]]
        >>> etl.header(table)
        ('foo', 'bar')

    Note that the header row will always be returned as a tuple, regardless
    of what the underlying data are.

    )rO   rQ   r   )rw   r   r"   r"   r&   headerF  s   r   c                 C   s   t dd t| D S )a_  
    Return the string values of the header row. If the header row
    contains only strings, then this function is equivalent to header(), i.e.::

        >>> import petl as etl
        >>> table = [['foo', 'bar'], ['a', 1], ['b', 2]]
        >>> etl.fieldnames(table)
        ('foo', 'bar')
        >>> etl.header(table)
        ('foo', 'bar')

    c                 s   s    | ]}t |V  qd S r;   r   r)   fr"   r"   r&   r+   i      zfieldnames.<locals>.<genexpr>)rQ   r   )rw   r"   r"   r&   
fieldnames[  s   r   c                 G   rc   )a  
    Return a container supporting iteration over data rows in a given table
    (i.e., without the header). E.g.::

        >>> import petl as etl
        >>> table = [['foo', 'bar'], ['a', 1], ['b', 2]]
        >>> d = etl.data(table)
        >>> list(d)
        [['a', 1], ['b', 2]]

    Positional arguments can be used to slice the data rows. The sliceargs
    are passed to :func:`itertools.islice`.

    )DataViewrw   	sliceargsr"   r"   r&   datao  s   r   c                   @   r   )r   c                 G   s   || _ || _d S r;   r   )r#   rw   r   r"   r"   r&   r{        
zDataView.__init__c                 C   s   t | jg| jR  S r;   )iterdatarw   r   r.   r"   r"   r&   r=     s   zDataView.__iter__Nr   r"   r"   r"   r&   r     s    r   c                 G   s$   t | dd }|rt |g|R  }|S Nr(   rh   )rw   r   r   r"   r"   r&   r     s   r   c                 O   rZ   )a  
    Return a container supporting iteration over rows as dicts. E.g.::

        >>> import petl as etl
        >>> table = [['foo', 'bar'], ['a', 1], ['b', 2]]
        >>> d = etl.dicts(table)
        >>> d
        {'foo': 'a', 'bar': 1}
        {'foo': 'b', 'bar': 2}
        >>> list(d)
        [{'foo': 'a', 'bar': 1}, {'foo': 'b', 'bar': 2}]

    Short rows are padded with the value of the `missing` keyword argument.

    )	DictsViewrw   r   rE   r"   r"   r&   dicts  s   r   c                   @   rz   )r   c                 O      || _ || _|| _d S r;   r   r#   rw   r   rE   r"   r"   r&   r{        
zDictsView.__init__c                 C      t | jg| jR i | jS r;   )	iterdictsrw   r   rE   r.   r"   r"   r&   r=        zDictsView.__iter__c                 C   >   t ttt| d}d|d d }t|dkr|d7 }|S Nr}   
r~   z
...rN   rY   r   r   r   rI   r   r"   r"   r&   r     
   zDictsView.__repr__Nr   r"   r"   r"   r&   r         r   c                 o   sh    | dd }t| }zt|}W n
 ty   Y d S w |r&t|g|R  }|D ]	}t|||V  q(d S )Nr   )r   rO   r   r3   r   asdict)rw   r   rE   r   r   r   r   r"   r"   r&   r     s   r   c                    s   dd | D  z fddt t D }W t|S  tyK   t }t D ]\}}z| }W n ty=   |}Y nw |||f q(Y t|S w )Nc                 S   s   g | ]}t |qS r"   r   r   r"   r"   r&   
<listcomp>  s    zasdict.<locals>.<listcomp>c                    s   g | ]
} | | fqS r"   r"   )r)   r@   r   r   r"   r&   r     s    )rangerI   r4   rN   r>   r   rR   )r   r   r   itemsr@   r   vr"   r   r&   r     s    
r   c                 O   rZ   )a  
    View the table as a container of named tuples. E.g.::

        >>> import petl as etl
        >>> table = [['foo', 'bar'], ['a', 1], ['b', 2]]
        >>> d = etl.namedtuples(table)
        >>> d
        row(foo='a', bar=1)
        row(foo='b', bar=2)
        >>> list(d)
        [row(foo='a', bar=1), row(foo='b', bar=2)]

    Short rows are padded with the value of the `missing` keyword argument.

    The `name` keyword argument can be given to override the name of the
    named tuple class (defaults to 'row').

    )NamedTuplesViewr   r"   r"   r&   namedtuples  s   r   c                   @   rz   )r   c                 O   r   r;   r   r   r"   r"   r&   r{     r   zNamedTuplesView.__init__c                 C   r   r;   )iternamedtuplesrw   r   rE   r.   r"   r"   r&   r=     r   zNamedTuplesView.__iter__c                 C   r   r   r   r   r"   r"   r&   r     r   zNamedTuplesView.__repr__Nr   r"   r"   r"   r&   r     r   r   c           
      o   s    | dd }| dd}t| }zt|}W n
 ty!   Y d S w ttt|}t|t|}|r:t	|g|R  }|D ]	}	t
||	|V  q<d S )Nr   namer   )r   rO   r   r3   rN   rY   r   r   rQ   r   asnamedtuple)
rw   r   rE   r   r   r   r   r   ntr   r"   r"   r&   r   
  s    r   c                 C   st   z| | W S  t y9   t| j}t|}||kr*t||f||   }| |  Y S ||k r8| |d |   Y S  w r;   )	TypeErrorrI   _fieldsrQ   )r   r   r   nenapaddedr"   r"   r&   r     s   

r   c                       sJ   e Zd Zd fdd	ZdddZ fddZ fdd	Zdd
dZ  ZS )RecordNc                    s   t t| | |}|S r;   )rs   r   __new__)clsr   r   r   trt   r"   r&   r   0  s   zRecord.__new__c                 C   s   || _ || _d S r;   )r   r   )r#   r   r   r   r"   r"   r&   r{   4  r   zRecord.__init__c                    sr   t |tr|}n|| jv r| j|}ntdt| d t| j z	tt| |W S  t	y8   | j
 Y S w Nzitem z not in fields )r1   r2   r   rA   KeyErrorr   rs   r   r:   r4   r   )r#   r   r   rt   r"   r&   r:   8  s   


zRecord.__getitem__c                    s\   || j v rztt| | j |W S  ty   | j Y S w tdt| d t| j  r   )	r   rs   r   r:   rA   r4   r   AttributeErrorr   )r#   r   rt   r"   r&   __getattr__E  s   

zRecord.__getattr__c                 C   s"   z| | W S  t y   | Y S w r;   )r   )r#   keydefaultr"   r"   r&   r   O  s
   
z
Record.getr;   )	rn   ro   rp   r   r{   r:   r   r   rv   r"   r"   rt   r&   r   .  s    

r   c                 O   rZ   )an  
    Return a container supporting iteration over rows as records, where a
    record is a hybrid object supporting all possible ways of accessing values.
    E.g.::


        >>> import petl as etl
        >>> table = [['foo', 'bar'], ['a', 1], ['b', 2]]
        >>> d = etl.records(table)
        >>> d
        ('a', 1)
        ('b', 2)
        >>> list(d)
        [('a', 1), ('b', 2)]
        >>> [r[0] for r in d]
        ['a', 'b']
        >>> [r['foo'] for r in d]
        ['a', 'b']
        >>> [r.foo for r in d]
        ['a', 'b']

    Short rows are padded with the value of the `missing` keyword argument.

    )RecordsViewr   r"   r"   r&   recordsV  s   r   c                   @   rz   )r   c                 O   r   r;   r   r   r"   r"   r&   r{   x  r   zRecordsView.__init__c                 C   r   r;   )iterrecordsrw   r   rE   r.   r"   r"   r&   r=   }  r   zRecordsView.__iter__c                 C   r   r   r   r   r"   r"   r&   r     r   zRecordsView.__repr__Nr   r"   r"   r"   r&   r   v  r   r   c                 o   sx    | dd }t| }zt|}W n
 ty   Y d S w ttt|}|r-t|g|R  }|D ]
}t|||dV  q/d S )Nr   )r   )	r   rO   r   r3   rN   rY   r   r   r   )rw   r   rE   r   r   r   r   r   r"   r"   r&   r     s   r   Tc                 C   sn   t du r ta |dur |s tr zddl}ta W n	 ty   Y nw dd }tdu r-tdat	|| }t |S )al  
    Construct a function operating on a table record.

    The expression string is converted into a lambda function by prepending
    the string with ``'lambda rec: '``, then replacing anything enclosed in
    curly braces (e.g., ``"{foo}"``) with a lookup on the record (e.g.,
    ``"rec['foo']"``), then finally calling :func:`eval`.

    So, e.g., the expression string ``"{foo} * {bar}"`` is converted to the
    function ``lambda rec: rec['foo'] * rec['bar']``

    The ``trusted`` keyword argument can be used to specify whether the
    expression is trusted and doesn't contains any type of code injection.
    If the expression is trusted, it will be evaluated using ``eval``,
    otherwise it will be evaluated using the `asteval` library if available.

    Note that in further versions of petl, the default value of ``trusted`` 
    will change to ``False``.
    Nr   c                 S   s   d|  d S )Nz	rec['%s']r(   )group)matchobjr"   r"   r&   
_expr_repl  s   zexpr.<locals>._expr_replz\{([^}]+)\})

_expr_impl_unsafe_exprr   asteval
_safe_exprImportError_expr_regexrecompilesub)expression_texttrustedr   r   strexprr"   r"   r&   expr  s   
r   c                   @   rz   )PetlAstEvalc                 C   s*   ddl m} | | _d| }| | d S )Nr   )Interpreterzdef expr(rec):
    return %s
)r   r   aeval)r#   r   r   coder"   r"   r&   r{     s   zPetlAstEval.__init__c                 C   s   | j jS r;   )r   r   r.   r"   r"   r&   r     rJ   zPetlAstEval.__repr__c                 C   sR   || j jd< |  d}t| j jdkr'dd | j jD }d|}td| |S )Nrecz	expr(rec)r   c                 S   s   g | ]}|  d  qS ))	get_error)r)   er"   r"   r&   r     s    z(PetlAstEval.__call__.<locals>.<listcomp>r   z(Failed to evaluate expression due to: %s)r   symtablerI   errorr   r?   )r#   r   	evaluatederrmsgr"   r"   r&   __call__  s   

zPetlAstEval.__call__N)rn   ro   rp   r{   r   r   r"   r"   r"   r&   r     s    r   c                 C   s   t | }|S r;   )r   )r   	evaluatorr"   r"   r&   r     s   r   c                 C   s   t d u r!d d d d d d d d d d d d d da dd tjD }t | d|  }z	t|t t }|W S  tyB } ztd||f d }~ww )N)__builtins__ru   __package__
__loader____spec____file__
__cached____dict__
__import____path____main__rn   __doc__c                 S   s   i | ]	}d |vr|dqS ).Nr"   )r)   kr"   r"   r&   
<dictcomp>  s    z _unsafe_expr.<locals>.<dictcomp>zlambda rec: z)Invalid expression: "%s" causes error: %s)_RESTRICTEDsysmodulesupdateevalr?   )r   nomodsr   funver"   r"   r&   r     s2   
r   c           
         s   t | }zt|}W n ty   g }Y nw ttt|  fdd|D }t|r/|}d}nt||}t| }d}t	||d}|du rO|rH|S dd |D S t|rV|n
t||}	t
j|	 |rkfdd|D S fd	d|D S )
a  Convenient adapter for :func:`itertools.groupby`. E.g.::

        >>> import petl as etl
        >>> table1 = [['foo', 'bar', 'baz'],
        ...           ['a', 1, True],
        ...           ['b', 3, True],
        ...           ['b', 2]]
        >>> # group entire rows
        ... for key, group in etl.rowgroupby(table1, 'foo'):
        ...     print(key, list(group))
        ...
        a [('a', 1, True)]
        b [('b', 3, True), ('b', 2)]
        >>> # group specific values
        ... for key, group in etl.rowgroupby(table1, 'foo', 'bar'):
        ...     print(key, list(group))
        ...
        a [1]
        b [3, 2]

    N.B., assumes the input table is already sorted by the given key.

    c                 3   s    | ]}t | V  qd S r;   )r   )r)   r   )r   r"   r&   r+     s    zrowgroupby.<locals>.<genexpr>TF)r   Nc                 s   s    | ]
\}}|j |fV  qd S r;   r   r)   r  valsr"   r"   r&   r+   ,  s    c                 3   s*    | ]\}}| fd d|D fV  qdS )c                 3       | ]} |V  qd S r;   r"   r)   r   getvalr"   r&   r+   4  r   'rowgroupby.<locals>.<genexpr>.<genexpr>Nr"   r  r  r"   r&   r+   4  s    c                 3   s,    | ]\}}|j  fd d|D fV  qdS )c                 3   r  r;   r"   r  r  r"   r&   r+   7  r   r  Nr   r  r  r"   r&   r+   7  s     )rO   r   r3   rN   rY   r   callabler   r    r   r   r   )
rw   r   r   r   r   getkey
native_keykindicesgitvindicesr"   )r   r  r&   
rowgroupby  s<   




r  r(   c                 C   sD   t | } |dkrt| }|t|g| fS tt| |}|t|| fS r   )rO   r   r   rN   r   )r   npeekr"   r"   r&   iterpeek>  s   r"  c                   C   r   )a  
    Return an empty table. Can be useful when building up a table from a set
    of columns, e.g.::

        >>> import petl as etl
        >>> table = (
        ...     etl
        ...     .empty()
        ...     .addcolumn('foo', ['A', 'B'])
        ...     .addcolumn('bar', [1, 2])
        ... )
        >>> table
        +-----+-----+
        | foo | bar |
        +=====+=====+
        | 'A' |   1 |
        +-----+-----+
        | 'B' |   2 |
        +-----+-----+

    )
EmptyTabler"   r"   r"   r&   emptyH  s   r$  c                   @   s   e Zd Zdd ZdS )r#  c                 c   s    t  V  d S r;   r   r.   r"   r"   r&   r=   d  s   zEmptyTable.__iter__N)rn   ro   rp   r=   r"   r"   r"   r&   r#  b  s    r#  r;   )T)r(   )P
__future__r   r   r   r   r  	itertoolsr   r   r   r   r	   r
   r   r   r   r   r   r   collectionsr   r   r   r   r   petl.compatr   r   r   r   r   r   r   r   r   r   petl.errorsr   petl.comparisonr    objectr!   rq   ry   rr   r|   r   wrapr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rQ   r   r   r   r   r
  r   r   r   r   r   r   r  r"  r$  r#  r"   r"   r"   r&   <module>   sr    40 	+	


(
*
?

