
 X1                 @   s  d  Z  d d l m Z d d l m Z d d l m Z i
 d d 6d d 6d d 6d	 d
 6d d 6d d 6d d 6d d 6d d 6d d 6Z Gd d   d e  Z	 Gd d   d e  Z
 Gd d   d e  Z d d   Z d d   Z d d   Z d  d!   Z d" d#   Z d$ d%   Z d S)&a  
Functions for reversing a regular expression (used in reverse URL resolving).
Used internally by Django and not intended for external use.

This is not, and is not intended to be, a complete reg-exp decompiler. It
should be good enough for a large class of URLS, however.
    )unicode_literals)six)zipNAbB0dxD sSw!WZc               @   s   e  Z d  Z d Z d S)Choicez
    Used to represent multiple possibilities at this point in a pattern string.
    We use a distinguished type, rather than a list, so that the usage in the
    code is clear.
    N)__name__
__module____qualname____doc__ r   r   G/home/ubuntu/projects/ifolica/build/django/django/utils/regex_helper.pyr      s   r   c               @   s   e  Z d  Z d Z d S)GroupzD
    Used to represent a capturing group in the pattern string.
    N)r   r   r   r   r   r   r   r   r   &   s   r   c               @   s   e  Z d  Z d Z d S)
NonCapturezH
    Used to represent a non-capturing group in the pattern string.
    N)r   r   r   r   r   r   r   r   r   ,   s   r   c             C   s  g  } g  } d } t  t |    } d } y t |  \ } } Wn t k
 ra d g  f g SYn Xyx| r~ | j |  n| d k r | j d  n| d k r t d   nd| d k r nU| d k r PnE| d	 k r| j   } t | | d
   }	 | d
 |  |	 g } n| d k rt |  \ } } | j |  t |  \ } } x| sn| d k rt |  \ } } q\Wn| d k ret |  \ } } | d k s| rd | }
 | d 7} | j t d |
 |
 f   t	 | |  qt |  \ } } | d k r&t	 | |  q| d k rH| j t
 |   q| d k rgt d |   qt |  \ } } | d k rt d |   n  | d k rd } n d	 } g  }
 t |  \ } } x/ | | k r|
 j |  t |  \ } } qWd j |
  } | d	 k rE| j t d | | f   t	 | |  q| j t d | d
 f   n | d k rt | |  \ } } | rd } n  | d k rt | d t  rt d
 | d g  | d <q	| j   q| d k r| j | d  g | d  qn | j |  | r4t |  \ } } qh d } qh WWn0 t k
 rSYn t k
 rqd g  f g SYn Xt t t |     S)!az  
    Given a reg-exp pattern, normalizes it to an iterable of forms that
    suffice for reverse matching. This does the following:

    (1) For any repeating sections, keeps the minimum number of occurrences
        permitted (this means zero for optional groups).
    (2) If an optional group includes parameters, include one occurrence of
        that group (along with the zero occurrence case from step (1)).
    (3) Select the first (essentially an arbitrary) element from any character
        class. Select an arbitrary character for any unordered class (e.g. '.'
        or '\w') in the pattern.
    (4) Ignore comments, look-ahead and look-behind assertions, and any of the
        reg-exp flags that won't change what we construct ("iLmsu"). "(?x)" is
        an error, however.
    (5) Raise an error on any disjunctive ('|') constructs.

    Django's URLs for forward resolving are either all positional arguments or
    all keyword arguments. That is assumed here, as well. Although reverse
    resolving can be done using positional args when keyword args are
    specified, the two cannot be mixed in the same reverse() call.
    Tr    .|zAwaiting Implementation^$)N[](?z_%d   z%%(%s)sz	iLmsu#!=<:Pz&Non-reversible reg-exp portion: '(?%s'<=z'Non-reversible reg-exp portion: '(?P%s'>z*?+{F)r)   r*   r,   r,   r,   )	next_chariternextStopIterationappendNotImplementedErrorpopr   r   walk_to_endlen
ValueErrorjoinget_quantifiercontainsr   extendlistr   flatten_result)patternresultZnon_capturing_groupsZconsume_nextZpattern_iterZnum_argschescapedstartinnernameZterminal_charparamcountr   r   r   	normalize2   s    

	 	"rF   c             c   sm   xf |  D]^ } | d k r* | d f Vq n  t  |   } t j | |  } | d k rZ q n  | d f Vq Wd S)a  
    An iterator that yields the next character from "pattern_iter", respecting
    escape sequences. An escaped character is replaced by a representative of
    its class (e.g. \w -> "x"). If the escaped character is one that is
    skipped, it is not returned (the next character is returned instead).

    Yields the next character, along with a boolean indicating whether it is a
    raw (unescaped) character or not.
    \FNT)r/   ESCAPE_MAPPINGSget)
input_iterr?   Zrepresentativer   r   r   r-      s    
r-   c             C   s~   |  d k r d } n d } x\ | D]T \ }  } | r: q" q" |  d k rS | d 7} q" |  d k r" | si d S| d 8} q" q" Wd S)z
    The iterator is currently inside a capturing group. We want to walk to the
    close of this group, skipping over any nested groups and handling escaped
    parentheses correctly.
    r$   r&   r   r!   Nr   )r?   rJ   Znestingr@   r   r   r   r4      s    	r4   c             C   s,  |  d k rr y t  |  \ } } Wn t k
 r< d } Yn X| d k rR d } n  |  d k rh d | f Sd | f Sg  } x/ |  d k r t  |  \ }  } | j |   q{ W| d d
  } d j |  j d	  } y t  |  \ }  } Wn t k
 rd }  Yn X|  d k rd }  n  t | d  |  f S)a'  
    Parse a quantifier from the input, where "ch" is the first character in the
    quantifier.

    Returns the minimum number of occurrences permitted by the quantifier and
    either None or the next character from the input_iter if the next character
    is not part of the quantifier.
    z*?+Nr%   +r&   r   }r   ,r,   )r/   r0   r1   r7   splitint)r?   rJ   Zch2r@   Zquantvaluesr   r   r   r8      s.    		

	r8   c             C   sM   t  |  |  r d St  |  t  rI x$ |  D] } t | |  r) d Sq) Wn  d S)z\
    Returns True if the "source" contains an instance of "inst". False,
    otherwise.
    TF)
isinstancer   r9   )sourceinsteltr   r   r   r9     s    r9   c             C   s  |  d k r d g g  g f St  |  t  re |  d d k rD g  } n |  d g } |  d g | g f Sd g } g  g } d } } xt |   D]\ } } t  | t j  r q n  d j |  | |   } t  | t  r | | d 7} | d } n d } | d } xB t t |   D]. }	 | |	 | 7<| r| |	 j |  qqWt  | t	 t
 f  r t  | t
  rz| g } n  g  g  }
 } x: | D]2 } t |  \ } } |
 j |  | j |  qWg  } g  } xi t | |  D]X \ } } xI t |
 |  D]8 \ } } | j | |  | j | d d  |  qWqW| } | } q q W| | k rd j |  | d   } x+ t t |   D] }	 | |	 | 7<qWn  | | f S)z
    Turns the given source sequence into a list of reg-exp possibilities and
    their arguments. Returns a list of strings and a list of argument lists.
    Each of the two lists will be of the same length.
    Nr   r&   r   )rQ   r   	enumerater   string_typesr7   ranger5   r1   r   r   r<   r:   r   )rR   paramsr>   Zresult_argsposlastrT   ZpiecerD   iZinner_resultZ
inner_argsitemresargsZ
new_resultZnew_argsZi_itemZi_argsr   r   r   r<   *  sX    			

#r<   )r   
__future__r   Zdjango.utilsr   Zdjango.utils.six.movesr   rH   r;   r   r   r   rF   r-   r4   r8   r9   r<   r   r   r   r   <module>   s.   
%