3
(hdE                 @   sF  d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZmZ ddlmZ ddlmZ ddlmZmZ ddl m!Z! G dd de"Z#ejddd ddZ$ejdddd Z%G dd de"Z&G dd de&Z'G dd de&Z(G dd de(Z)dS )!a   
This module converts requested URLs to callback view functions.

RegexURLResolver is the main class here. Its resolve() method takes a URL (as
a string) and returns a ResolverMatch object which provides access to all
attributes of the resolved URL match.
    )unicode_literalsN)import_module)settings)ImproperlyConfigured)	lru_cachesix)MultiValueDict)	force_str
force_text)cached_property)RFC3986_SUBDELIMSurlquote)	normalize)get_language   )NoReverseMatchResolver404)get_callablec               @   s&   e Zd ZdddZdd Zdd ZdS )	ResolverMatchNc             C   s   || _ || _|| _|| _|r*dd |D ng | _dj| j| _|rPdd |D ng | _dj| j| _t	|dsdj|j
j|j
jg| _ndj|j|jg| _|p| j}dj| j|g | _d S )Nc             S   s   g | ]}|r|qS  r   ).0xr   r   9/tmp/pip-install-q3hcpn_q/Django/django/urls/resolvers.py
<listcomp>&   s    z*ResolverMatch.__init__.<locals>.<listcomp>:c             S   s   g | ]}|r|qS r   r   )r   r   r   r   r   r   (   s    __name__.)funcargskwargsurl_name	app_namesjoinapp_name
namespaces	namespacehasattr	__class__
__module__r   
_func_pathZ	view_name)selfr   r   r   r    r!   r$   Z	view_pathr   r   r   __init__   s    

zResolverMatch.__init__c             C   s   | j | j| jf| S )N)r   r   r   )r*   indexr   r   r   __getitem__5   s    zResolverMatch.__getitem__c             C   s    d| j | j| j| j| j| jf S )NzTResolverMatch(func=%s, args=%s, kwargs=%s, url_name=%s, app_names=%s, namespaces=%s))r)   r   r   r    r!   r$   )r*   r   r   r   __repr__8   s    zResolverMatch.__repr__)NNN)r   r(   __qualname__r+   r-   r.   r   r   r   r   r      s   
r   )maxsizec             C   s$   | d krddl m} |j} td| S )Nr   )r   z^/)django.confr   ZROOT_URLCONFRegexURLResolver)Zurlconfr   r   r   r   get_resolver?   s    r3   c             C   s   t | |j}t d|gS )Nz^/)r2   url_patterns)Z
ns_patternresolverZns_resolverr   r   r   get_ns_resolverG   s    r6   c               @   s$   e Zd ZdZdd Zedd ZdS )LocaleRegexProviderz\
    A mixin to provide a default regex property which can vary by active
    language.
    c             C   s   || _ i | _d S )N)_regex_regex_dict)r*   regexr   r   r   r+   U   s    zLocaleRegexProvider.__init__c             C   s   t  }|| jkrt| jtjr$| jnt| j}ytj|tj	}W n: tj
k
rz } ztd|tj|f W Y dd}~X nX || j|< | j| S )zV
        Return a compiled regular expression based on the activate language.
        z*"%s" is not a valid regular expression: %sN)r   r9   
isinstancer8   r   string_typesr
   recompileUNICODEerrorr   	text_type)r*   language_coder:   Zcompiled_regexer   r   r   r:   \   s    
$
zLocaleRegexProvider.regexN)r   r(   r/   __doc__r+   propertyr:   r   r   r   r   r7   P   s   r7   c               @   s2   e Zd Zd
ddZdd Zdd Zedd	 ZdS )RegexURLPatternNc             C   s&   t j| | || _|pi | _|| _d S )N)r7   r+   callbackdefault_argsname)r*   r:   rG   rH   rI   r   r   r   r+   p   s    
zRegexURLPattern.__init__c             C   s   t d| jj| j| jjf S )Nz
<%s %s %s>)r	   r'   r   rI   r:   pattern)r*   r   r   r   r.   v   s    zRegexURLPattern.__repr__c             C   sJ   | j j|}|rF|j }|r f n|j }|j| j t| j||| jS d S )N)	r:   search	groupdictgroupsupdaterH   r   rG   rI   )r*   pathmatchr   r   r   r   r   resolvey   s    zRegexURLPattern.resolvec             C   sd   | j }xt|tjr|j}qW t|ds:|jd |jj S t	j
rP|jd |j S |jd |j S dS )zw
        A string that identifies the view (e.g. 'path.to.view_function' or
        'path.to.ClassBasedView').
        r   r   N)rG   r;   	functoolspartialr   r&   r(   r'   r   r   PY3r/   )r*   rG   r   r   r   
lookup_str   s    

zRegexURLPattern.lookup_str)NN)r   r(   r/   r+   r.   rQ   r   rU   r   r   r   r   rF   o   s   
rF   c               @   s   e Zd ZdddZdd Zdd Zedd	 Zed
d Zedd Z	dd Z
dd Zedd Zedd Zdd Zdd Zdd ZdS )r2   Nc             C   s\   t j| | || _d | _|pi | _|| _|| _i | _i | _i | _	t
 | _d| _tj | _d S )NF)r7   r+   urlconf_namerG   default_kwargsr%   r#   _reverse_dict_namespace_dict	_app_dictset_callback_strs
_populated	threadinglocal_local)r*   r:   rV   rW   r#   r%   r   r   r   r+      s    
zRegexURLResolver.__init__c             C   sV   t | jtr*t| jr*d| jd jj }n
t| j}td| jj|| j| j	| j
jf S )Nz	<%s list>r   z<%s %s (%s:%s) %s>)r;   rV   listlenr'   r   reprstrr#   r%   r:   rJ   )r*   Zurlconf_reprr   r   r   r.      s    
zRegexURLResolver.__repr__c          
   C   s
  t | jddrd S d| j_t }i }i }t }xt| jD ]}t|trZ| j	j
|j |jj}|jdrx|dd  }t|tr|jr||f||j< |jr|j|jg j|j n|jj}xV|jD ]L}xF|jj|D ]6\}	}
}t||
 }|j||||
 t|f|jf qW qW x,|jj D ]\}\}}|| |f||< q"W x*|jj D ]\}}|j|g j| qPW t |jdds|j  | j	j|j	 q<t|}|j|j |||j!f |j"d k	r<|j|j"|||j!f q<W || j#|< || j$|< || j%|< d| _&d| j_d S )N
populatingFT^r   )'getattrr`   re   r   r   reversedr4   r;   rF   r\   addrU   r:   rJ   
startswithr2   r%   r#   
setdefaultappendreverse_dictgetlistr   Z
appendlistdictrW   namespace_dictitemsapp_dictextend	_populaterN   rG   rH   rI   rX   rY   rZ   r]   )r*   Zlookupsr$   ZappsrB   rJ   Z	p_patternZ
parent_patrI   matchespatdefaultsZnew_matchesr%   prefixZsub_patternr#   Znamespace_listbitsr   r   r   rt      sV    





zRegexURLResolver._populatec             C   s"   t  }|| jkr| j  | j| S )N)r   rX   rt   )r*   rB   r   r   r   rm      s    
zRegexURLResolver.reverse_dictc             C   s"   t  }|| jkr| j  | j| S )N)r   rY   rt   )r*   rB   r   r   r   rp      s    
zRegexURLResolver.namespace_dictc             C   s"   t  }|| jkr| j  | j| S )N)r   rZ   rt   )r*   rB   r   r   r   rr      s    
zRegexURLResolver.app_dictc             C   s   | j s| j  || jkS )N)r]   rt   r\   )r*   rI   r   r   r   _is_callback  s    zRegexURLResolver._is_callbackc       
         s>  t |}g }| jj|}|r.||j d  }x| jD ] y j|}W n` tk
r } zD|jd jd}|d k	r|j	 fdd|D  n|j
 g W Y d d }~X q6X |rt|j f| j}|j|j |j}	|s|j |j }	t|j|	||j| jg|j | jg|j S |j
 g q6W t||dtd|id S )Nr   triedc             3   s   | ]} g| V  qd S )Nr   )r   t)rJ   r   r   	<genexpr>  s    z+RegexURLResolver.resolve.<locals>.<genexpr>)r{   rO   rO   )r
   r:   rK   endr4   rQ   r   r   getrs   rl   ro   rL   rW   rN   r   rM   r   r   r    r#   r!   r%   r$   )
r*   rO   r{   rP   new_pathZ	sub_matchrC   Z	sub_triedZsub_match_dictZsub_match_argsr   )rJ   r   rQ     s:    zRegexURLResolver.resolvec             C   s"   t | jtjrt| jS | jS d S )N)r;   rV   r   r<   r   )r*   r   r   r   urlconf_module/  s    
zRegexURLResolver.urlconf_modulec             C   sL   t | jd| j}yt| W n* tk
rF   d}t|j| jdY nX |S )NZurlpatternszThe included URLconf '{name}' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.)rI   )rg   r   iter	TypeErrorr   formatrV   )r*   patternsmsgr   r   r   r4   6  s    zRegexURLResolver.url_patternsc             C   s<   t | jd| d }|s0ddlm} t |d| }t|i fS )Nz	handler%sr   )urls)rg   r   r1   r   r   )r*   Z	view_typerG   r   r   r   r   resolve_error_handlerE  s
    z&RegexURLResolver.resolve_error_handlerc             O   s   | j |df||S )N )_reverse_with_prefix)r*   lookup_viewr   r   r   r   r   reverseN  s    zRegexURLResolver.reversec             O   s  |r|rt ddd |D }dd |j D }| js>| j  | jj|}x"|D ]\}}	}
x
|D ] \}}|rt|t|krqftt||}nht	|j
 t	|
j
 B t	|t	|
j
 B krqfd}x*|
j D ]\}}|j|||krd}P qW |sqf|}|jdd	| }tjd
tj||	f || tjrft|| ttd d}|jdrdd|dd   }|S qfW qRW t|dd }t|dd }|d k	r|d k	rd||f }n|}dd |D }td|||t||f d S )Nz2Don't mix *args and **kwargs in call to reverse()!c             S   s   g | ]}t |qS r   )r
   )r   vr   r   r   r   T  s    z9RegexURLResolver._reverse_with_prefix.<locals>.<listcomp>c             S   s   i | ]\}}t ||qS r   )r
   )r   kr   r   r   r   
<dictcomp>U  s    z9RegexURLResolver._reverse_with_prefix.<locals>.<dictcomp>TF%z%%z^%s%sz/~:@)safez//z/%%2F%s   r(   r   z%s.%sc             S   s   g | ]\}}}|qS r   r   )r   possibilityrJ   rw   r   r   r   r     s    zbReverse for '%s' with arguments '%s' and keyword arguments '%s' not found. %d pattern(s) tried: %s)
ValueErrorrq   r]   rt   rm   rn   rb   ro   zipr[   keysr   replacer=   rK   escaper?   r   r   rd   rj   rg   r   )r*   r   _prefixr   r   Z	text_argsZtext_kwargspossibilitiesr   rJ   rw   resultparamsZcandidate_subsru   r   r   Zcandidate_paturlmnZlookup_view_sr   r   r   r   r   Q  sN    "z%RegexURLResolver._reverse_with_prefix)NNN)r   r(   r/   r+   r.   rt   rE   rm   rp   rr   rz   rQ   r   r   r4   r   r   r   r   r   r   r   r2      s   
6'	r2   c                   s.   e Zd ZdZd fdd	Zedd Z  ZS )	LocaleRegexURLResolverz
    A URL resolver that always matches the active language code as URL prefix.

    Rather than taking a regex argument, we just override the ``regex``
    function to always return the active language-code as regex.
    NTc                s"   t t| jd |||| || _d S )N)superr   r+   prefix_default_language)r*   rV   rW   r#   r%   r   )r'   r   r   r+     s    
zLocaleRegexURLResolver.__init__c             C   sT   t  p
tj}|| jkrJ|tjkr.| j r.d}nd| }tj|tj| j|< | j| S )Nr   z^%s/)r   r   ZLANGUAGE_CODEr9   r   r=   r>   r?   )r*   rB   Zregex_stringr   r   r   r:     s    
zLocaleRegexURLResolver.regex)NNNT)r   r(   r/   rD   r+   rE   r:   __classcell__r   r   )r'   r   r     s    r   )N)*rD   
__future__r   rR   r=   r^   	importlibr   r1   r   Zdjango.core.exceptionsr   Zdjango.utilsr   r   Zdjango.utils.datastructuresr   Zdjango.utils.encodingr	   r
   Zdjango.utils.functionalr   Zdjango.utils.httpr   r   Zdjango.utils.regex_helperr   Zdjango.utils.translationr   
exceptionsr   r   utilsr   objectr   r3   r6   r7   rF   r2   r   r   r   r   r   <module>   s2   "
	* t