
^Q\G                 @   s:  d  d l  m Z m Z d  d l m Z d  d l m Z d  d l m Z d  d l	 m
 Z
 d  d l m Z d  d l m Z d  d l m Z Gd	 d
   d
 e  Z Gd d   d e  Z e j Gd d   d e   Z Gd d   d e  Z e Z Gd d   d e  Z d d   Z d d   Z d d   Z d d d  Z d S)    )absolute_importunicode_literals)OrderedDict)total_ordering)chain)models)FieldDoesNotExist)six)format_html_joinc               @   s"   e  Z d  Z d Z d d   Z d S)Sequencea  
    Represents a column sequence, e.g. ``('first_name', '...', 'last_name')``

    This is used to represent `.Table.Meta.sequence` or the `.Table`
    constructors's *sequence* keyword argument.

    The sequence must be a list of column names and is used to specify the
    order of the columns on a table. Optionally a '...' item can be inserted,
    which is treated as a *catch-all* for column names that aren't explicitly
    specified.
    c             C   s   |  j  d  } | d k r* t d   n | d k rF |  j d  n  t |  } g  } g  } | } xX |  D]P } | d k r | } qk n  | j |  | | k rk | j | j |   qk qk Wt | | |  |  d d  <|  S)aR  
        Expands the ``'...'`` item in the sequence into the appropriate column
        names that should be placed there.

        arguments:
            columns (list): list of column names.
        returns:
            The current instance.

        raises:
            `ValueError` if the sequence is invalid for the columns.
        z...   z.'...' must be used at most once in a sequence.r   N)count
ValueErrorappendlistpopindexr   )selfcolumnsZellipsesheadtailtargetname r   I/var/www/dbchiro/venv/lib/python3.4/site-packages/django_tables2/utils.pyexpand   s$    zSequence.expandN)__name__
__module____qualname____doc__r   r   r   r   r   r      s   r   c               @   sp   e  Z d  Z d Z d Z e d d    Z e d d    Z e d d    Z e d	 d
    Z	 d d   Z
 d S)OrderByz|
    A single item in an `.OrderByTuple` object. This class is essentially just
    a `str` with some extra properties.
    __c             C   s.   |  d d  d k r* t  |  d d   S|  S)z
        Returns:
            `.OrderBy`: the bare form.

        The *bare form* is the non-prefixed form. Typically the bare form is
        just the ascending form.

        Example: ``age`` is the bare form of ``-age``

        Nr   -)r    )r   r   r   r   bareG   s    zOrderBy.barec             C   s+   |  j  r t |  d d   St d |   S)a  
        Provides the opposite of the current sorting directon.

        Returns:
            `.OrderBy`: object with an opposite sort influence.

        Example::

            >>> order_by = OrderBy('name')
            >>> order_by.opposite
            '-name'

        r   Nr"   )is_descendingr    )r   r   r   r   oppositeU   s    zOrderBy.oppositec             C   s   |  j  d  S)zN
        Returns `True` if this object induces *descending* ordering.
        r"   )
startswith)r   r   r   r   r$   f   s    zOrderBy.is_descendingc             C   s   |  j  S)zM
        Returns `True` if this object induces *ascending* ordering.
        )r$   )r   r   r   r   is_ascendingm   s    zOrderBy.is_ascendingc             C   s   |  j  t j t j  S)zf
        Returns the current instance usable in Django QuerySet's order_by
        arguments.
        )replaceAccessor	SEPARATORr    QUERYSET_SEPARATOR)r   r   r   r   for_querysett   s    zOrderBy.for_querysetN)r   r   r   r   r+   propertyr#   r%   r$   r'   r,   r   r   r   r   r    ?   s   r    c                   s   e  Z d  Z d Z   f d d   Z d d   Z d d   Z   f d d	   Z e d
 d    Z	 d d   Z
 e d d    Z   S)OrderByTuplea  
    Stores ordering as (as `.OrderBy` objects). The `~.Table.order_by` property
    is always converted to an `.OrderByTuple` object.

    This class is essentially just a `tuple` with some useful extras.

    Example::

        >>> x = OrderByTuple(('name', '-age'))
        >>> x['age']
        '-age'
        >>> x['age'].is_descending
        True
        >>> x['age'].opposite
        'age'

    c                s[   g  } x9 | D]1 } t  | t  s1 t |  } n  | j |  q Wt t |   j |  |  S)N)
isinstancer    r   superr.   __new__)clsiterableZtransformeditem)	__class__r   r   r1      s    zOrderByTuple.__new__c             C   s   d j  |   S)N,)join)r   r   r   r   __str__   s    zOrderByTuple.__str__c             C   s7   t  |  j } x! |  D] } | j | k r d Sq Wd S)a  
        Determine if a column has an influence on ordering.

        Example::

            >>> x = OrderByTuple(('name', ))
            >>> 'name' in  x
            True
            >>> '-name' in x
            True

        Arguments:
            name (str): The name of a column. (optionally prefixed)

        Returns:
            bool: `True` if the column with `name` influences the ordering.
        TF)r    r#   )r   r   order_byr   r   r   __contains__   s
    zOrderByTuple.__contains__c                sa   t  | t j  rK x- |  D]% } | | k s: | j | k r | Sq Wt  n  t t |   j |  S)a  
        Allows an `.OrderBy` object to be extracted via named or integer
        based indexing.

        When using named based indexing, it's fine to used a prefixed named::

            >>> x = OrderByTuple(('name', '-age'))
            >>> x[0]
            'name'
            >>> x['age']
            '-age'
            >>> x['-age']
            '-age'

        Arguments:
            index (int): Index to query the ordering for.

        Returns:
            `.OrderBy`: for the ordering at the index.
        )r/   r	   Zstring_typesr#   KeyErrorr0   r.   __getitem__)r   r   r9   )r5   r   r   r<      s    	zOrderByTuple.__getitem__c                sl   g    g   x4 |  D], }   j  t | j    j  | j  q Wt G   f d d   d t   } | S)Nc                   sC   e  Z d  Z d d   Z   f d d   Z    f d d   Z d S)z$OrderByTuple.key.<locals>.Comparatorc             S   s   | |  _  d  S)N)obj)r   r=   r   r   r   __init__   s    z-OrderByTuple.key.<locals>.Comparator.__init__c                sU   xN   D]F } | j  |  j d d } | j  | j d d } | | k s d Sq Wd S)NquietTF)resolver=   )r   otheraccessorab)	accessorsr   r   __eq__   s    z+OrderByTuple.key.<locals>.Comparator.__eq__c                s  xt  j j     D] \ } } | j |  j d d } | j | j d d } | | k rd q n  | rz | | } } n  y | | k  SWq t k
 rt |  t |  k	 r t |  t |  k  St |  } t |  } t |  t	 |  f t |  t	 |  f k  SYq Xq Wd S)Nr?   TF)
r	   Zmoveszipr@   r=   	TypeErrorbooltypereprid)r   rA   rB   reverserC   rD   Za_typeZb_type)rE   	reversingr   r   __lt__   s     "7z+OrderByTuple.key.<locals>.Comparator.__lt__N)r   r   r   r>   rF   rO   r   )rE   rN   r   r   
Comparator   s   rP   )r   r)   r#   r$   r   object)r   r9   rP   r   )rE   rN   r   key   s    $zOrderByTuple.keyc             C   s/   y |  | SWn t  t f k
 r* | SYn Xd S)zH
        Identical to __getitem__, but supports fallback value.
        N)r;   
IndexError)r   rR   fallbackr   r   r   get   s    zOrderByTuple.getc             C   s   t  |   d d   |  D  S)z
        Return version with each `.OrderBy` prefix toggled::

            >>> order_by = OrderByTuple(('name', '-age'))
            >>> order_by.opposite
            ('-name', 'age')
        c             s   s   |  ] } | j  Vq d  S)N)r%   ).0or   r   r   	<genexpr>  s    z(OrderByTuple.opposite.<locals>.<genexpr>)rJ   )r   r   r   r   r%     s    	zOrderByTuple.opposite)r   r   r   r   r1   r8   r:   r<   r-   rR   rU   r%   r   r   )r5   r   r.   |   s   /	r.   c               @   sg   e  Z d  Z d Z d Z d Z d Z d d d d  Z e d	 d
    Z	 d d   Z
 d d d  Z d S)r)   z
    A string describing a path from one object to another via attribute/index
    accesses. For convenience, the class has an alias `.A` to allow for more concise code.

    Relations are separated by a ``.`` character.
    .z9Refusing to call {method}() because `.alters_data = True`zRFailed lookup for key [{key}] in {context}, when resolving the accessor {accessor}TFc          !   C   s  yu| } xd|  j  D]Y} y | | } Wn t t t f k
 r y t | |  } Wn t t f k
 r y | t |  } Wni t t t t f k
 r t | t	 j
  r t |  n | } t |  j j d | d | d |     Yn XYn XYn Xt |  r\| r;t | d d  r;t |  j j d t |     n  t | d d  s\|   } q\n  | d k r Pq q W| SWn t k
 r| s  n  Yn Xd S)	a  
        Return an object described by the accessor by traversing the attributes
        of *context*.

        Lookups are attempted in the following order:

         - dictionary (e.g. ``obj[related]``)
         - attribute (e.g. ``obj.related``)
         - list-index lookup (e.g. ``obj[int(related)]``)

        Callable objects are called, and their result is used, before
        proceeding with the resolving.

        Example::

            >>> x = Accessor('__len__')
            >>> x.resolve('brad')
            4
            >>> x = Accessor('0.upper')
            >>> x.resolve('brad')
            'B'

        Arguments:
            context (object): The root/first object to traverse.
            safe (bool): Don't call anything with `alters_data = True`
            quiet (bool): Smother all exceptions and instead return `None`

        Returns:
            target object

        Raises:
            TypeError`, `AttributeError`, `KeyError`, `ValueError`
            (unless `quiet` == `True`)
        rR   contextrB   Zalters_dataFmethodZdo_not_call_in_templatesN)bitsrH   AttributeErrorr;   getattrintrS   r   r/   r   ZModelrJ   LOOKUP_ERROR_FMTformatcallableALTERS_DATA_ERROR_FMTrK   	Exception)r   rZ   safer?   currentbitZcurrent_contextr   r   r   r@     s<    $$3!zAccessor.resolvec             C   s    |  d k r f  S|  j  |  j  S)N )splitr*   )r   r   r   r   r\   h  s    zAccessor.bitsc             C   s   t  | d  s d Sd } xs |  j D]h } y | j j |  } Wn t k
 rT PYn Xt  | d  r# t | d d  } t | d |  } q# q# W| S)zZ
        Return the django model field for model in context, following relations.
        _metaNZremote_fieldmodel)hasattrr\   rj   	get_fieldr   r^   )r   rk   fieldrg   relr   r   r   rm   n  s    zAccessor.get_fieldc             C   s7   |  j  d  \ } } } t |  j | d | | f S)a  
        Split the accessor on the right-most dot '.', return a tuple with:
         - the resolved left part.
         - the remainder

        Example::

            >>> Accessor('a.b.c').penultimate({'a': {'a': 1, 'b': {'c': 2, 'd': 4}}})
            ({'c': 2, 'd': 4}, 'c')

        rY   r?   )
rpartitionAr@   )r   rZ   r?   path_	remainderr   r   r   penultimate  s    zAccessor.penultimateN)r   r   r   r   r*   rc   r`   r@   r-   r\   rm   ru   r   r   r   r   r)     s   Jr)   c               @   s4   e  Z d  Z d Z d
 Z d d   Z d d   Z d	 S)AttributeDicta$  
    A wrapper around `collections.OrderedDict` that knows how to render itself
    as HTML style tag attributes.

    Any key with ``value is None`` will be skipped.

    The returned string is marked safe, so it can be used safely in a template.
    See `.as_html` for a usage example.
    thtd	_orderingc             c   sh   xa t  j |   D]P \ } } t |  r1 |   n | } | |  j k r | d  k	 r | | f Vq q Wd  S)N)r	   	iteritemsrb   	blacklist)r   kvvaluer   r   r   
_iteritems  s    zAttributeDict._iteritemsc             C   s   t  d d |  j    S)ay  
        Render to HTML tag attributes.

        Example:

        .. code-block:: python

            >>> from django_tables2.utils import AttributeDict
            >>> attrs = AttributeDict({'class': 'mytable', 'id': 'someid'})
            >>> attrs.as_html()
            'class="mytable" id="someid"'

        returns: `~django.utils.safestring.SafeUnicode` object

         z{}="{}")r
   r   )r   r   r   r   as_html  s    zAttributeDict.as_htmlN)zthztdry   )r   r   r   r   r{   r   r   r   r   r   r   rv     s   	rv   c       
      c   s  |  p	 | s d Sx| j    D] \ } } i t |  | 6t |  j t |  j 6} x | j    D] \ } } t |  d t |    t |  k rb t |  } | | =|  t |  d  } | r xB t | |  D] }	 t t	 | g |	   Vq Wqb qt | g  Vqb qb Wq Wd S)a  
    Translates a flat sequence of items into a set of prefixed aliases.

    This allows the value set by `.QuerySet.order_by` to be translated into
    a list of columns that would have the same result. These are called
    "order by aliases" which are optionally prefixed column names::

        >>> list(segment(('a', '-b', 'c'),
        ...              {'x': ('a'),
        ...               'y': ('b', '-c'),
        ...               'z': ('-b', 'c')}))
        [('x', '-y'), ('x', 'z')]

    N)
itemsr.   r%   r    r   lendictsegmenttupler   )
sequencealiasesaliaspartsZvariantsZvaliasZvpartsZtail_aliasesZtail_sequencer   r   r   r   r     s     (r   c             C   s  d d l  } t j r{ | j |   } | j } t |  d k rn t | d d k rb | d d  n |  } n  | | j f S| j |   } g  } d } x] | j	 j
   D]L } | j | j k r | j } q | j | j k r q q | j | j  q Wt |  | f S)z
    Returns:
        tuple: Returns a (arguments, kwarg_name)-tuple:
             - the arguments (positional or keyword)
             - the name of the ** kwarg catch all.

    The self-argument for methods is always removed.
    r   Nr   r   )inspectr	   ZPY2Z
getargspecargsr   r   keywords	signature
parametersvalueskindZVAR_KEYWORDr   ZVAR_POSITIONALr   )fnr   Zargspecr   r   r   argr   r   r   r     s"    			/r   c                sd   t  |   \   } | sZ    f d d    D  t  f d d     D  rZ d Sn  |     S)aE  
    Calls the function ``fn`` with the keyword arguments from ``kwargs`` it expects

    If the kwargs argument is defined, pass all arguments, else provide exactly
    the arguments wanted.

    If one of the arguments of ``fn`` are not contained in kwargs, ``fn`` will not
    be called and ``None`` will be returned.
    c                s)   i  |  ] } |   k r  | |  q Sr   r   )rV   rR   )r   kwargsr   r   
<dictcomp>  s   	 z)call_with_appropriate.<locals>.<dictcomp>c             3   s   |  ] } |   k Vq d  S)Nr   )rV   r   )r   r   r   rX     s    z(call_with_appropriate.<locals>.<genexpr>N)r   any)r   r   Zkwargs_namer   )r   r   r   call_with_appropriate  s    
r   Nc             C   s   | p	 i  } i  } xl t  j |   D][ \ } } t |  rO t | d | } n  t | t  rs t | d | } n  | | | <q" W| S)a#  
    Returns a new `dict` that has callable values replaced with the return values.

    Example::

        >>> compute_values({'foo': lambda: 'bar'})
        {'foo': 'bar'}

    Arbitrarily deep structures are supported. The logic is as follows:

    1. If the value is callable, call it and make that the new value.
    2. If the value is an instance of dict, use ComputableDict to compute its keys.

    Example::

        >>> def parents():
        ...     return {
        ...         'father': lambda: 'Foo',
        ...         'mother': 'Bar'
        ...      }
        ...
        >>> a = {
        ...     'name': 'Brad',
        ...     'parents': parents
        ... }
        ...
        >>> computed_values(a)
        {'name': 'Brad', 'parents': {'father': 'Foo', 'mother': 'Bar'}}

    Arguments:
        d (dict): The original dictionary.
        kwargs: any extra keyword arguments will be passed to the callables, if the callable
            takes an argument with such a name.

    Returns:
        dict: with callable values replaced.
    r   )r	   rz   rb   r   r/   r   computed_values)dr   resultr|   r}   r   r   r   r     s    &r   )
__future__r   r   collectionsr   	functoolsr   	itertoolsr   Z	django.dbr   Zdjango.db.models.fieldsr   Zdjango.utilsr	   Zdjango.utils.htmlr
   r   r   strr    Zpython_2_unicode_compatibler   r.   r)   rq   rv   r   r   r   r   r   r   r   r   <module>   s$   1=%%%