B
    ª0H[àb  ã               @   s~  d 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 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 ddlmZ ddlmZmZ ddlm Z  G dd„ dƒZ!ej"dd�d+dd„ƒZ#ej"dd�dd„ ƒZ$G dd„ dƒZ%G dd„ dƒZ&G dd„ de&ƒZ'e (d¡Z)d,d!d"„Z*G d#d$„ d$e&ƒZ+G d%d&„ d&ƒZ,G d'd(„ d(ƒZ-G d)d*„ d*ƒZ.dS )-zû
This module converts requested URLs to callback view functions.

URLResolver 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.
é    N)Úimport_module)Úquote)Úsettings)ÚWarning)Úcheck_resolver)ÚImproperlyConfigured)ÚMultiValueDict)Úcached_property)ÚRFC3986_SUBDELIMS)Ú	normalize)Úget_languageé   )Úget_converter)Ú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¡| _|rPdd„ |D ƒng | _d | j¡| _t	|dƒs†|j
jd |j
j | _n|jd |j | _|p | j}d | j|g ¡| _d S )Nc             S   s   g | ]}|r|‘qS © r   )Ú.0Úxr   r   úYC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6bm3nxem\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tdƒ| ƒS )Nr   )r   z^/)Údjango.confr   ZROOT_URLCONFÚURLResolverÚRegexPattern)Zurlconfr   r   r   r   Úget_resolver?   s    r2   c             C   s.   t | ƒ}t|ƒ|_t||jƒ}tt dƒ|gƒS )Nz^/)r1   ÚdictÚ
convertersr0   Úurl_patterns)Z
ns_patternÚresolverr4   ÚpatternZns_resolverr   r   r   Úget_ns_resolverG   s    
r8   c               @   s   e Zd Zdd„ Zddd„ZdS )ÚLocaleRegexDescriptorc             C   s
   || _ d S )N)Úattr)r(   r:   r   r   r   r)   S   s    zLocaleRegexDescriptor.__init__Nc             C   sj   |dkr| S t || jƒ}t|tƒr<| |¡|jd< |jd S tƒ }||jkr`| t|ƒ¡|j|< |j| S )zT
        Return a compiled regular expression based on the active language.
        NÚregex)Úgetattrr:   Ú
isinstanceÚstrÚ_compileÚ__dict__r   Ú_regex_dict)r(   ÚinstanceÚclsr7   Úlanguage_coder   r   r   Ú__get__V   s    


zLocaleRegexDescriptor.__get__)N)r   r&   r-   r)   rE   r   r   r   r   r9   R   s   r9   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚCheckURLMixinc             C   s$   d  | ¡}| jr |d  | j¡7 }|S )zI
        Format the URL pattern for display in warning messages.
        z'{}'z [name='{}'])ÚformatÚname)r(   Údescriptionr   r   r   Údescribej   s    
zCheckURLMixin.describec             C   sJ   | j j}tjsg S | d¡rB| d¡sBtd |  ¡ ¡dd�}|gS g S dS )zM
        Check that the pattern does not begin with a forward slash.
        )ú/z^/z^\/rK   z»Your URL pattern {} has a route beginning with a '/'. Remove this slash as it is unnecessary. If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'.z	urls.W002)ÚidN)	r;   r7   r   ZAPPEND_SLASHÚ
startswithÚendswithr   rG   rJ   )r(   Úregex_patternÚwarningr   r   r   Ú_check_pattern_startswith_slashs   s    z-CheckURLMixin._check_pattern_startswith_slashN)r   r&   r-   rJ   rQ   r   r   r   r   rF   i   s   	rF   c               @   sF   e Zd ZedƒZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )r1   Ú_regexNFc             C   s"   || _ i | _|| _|| _i | _d S )N)rR   rA   Ú_is_endpointrH   r4   )r(   r;   rH   Úis_endpointr   r   r   r)   �   s
    zRegexPattern.__init__c             C   sB   | j  |¡}|r>| ¡ }|r dn| ¡ }|| ¡ d … ||fS d S )Nr   )r;   ÚsearchÚ	groupdictÚgroupsÚend)r(   ÚpathÚmatchr   r   r   r   r   rZ   ”   s    zRegexPattern.matchc             C   s*   g }|  |  ¡ ¡ | js&|  |  ¡ ¡ |S )N)ÚextendrQ   rS   Ú_check_include_trailing_dollar)r(   Úwarningsr   r   r   ÚcheckŸ   s
    zRegexPattern.checkc             C   s<   | j j}| d¡r4| d¡s4td |  ¡ ¡dd�gS g S d S )Nú$z\$zƒYour URL pattern {} uses include with a route ending with a '$'. Remove the dollar from the route to avoid problems including URLs.z	urls.W001)rL   )r;   r7   rN   r   rG   rJ   )r(   rO   r   r   r   r\   ¦   s    
z+RegexPattern._check_include_trailing_dollarc          
   C   sD   y
t  |¡S  t jk
r> } ztd||f ƒ‚W dd}~X Y nX dS )z0Compile and return the given regular expression.z*"%s" is not a valid regular expression: %sN)ÚreÚcompileÚerrorr   )r(   r;   Úer   r   r   r?   ²   s
    
zRegexPattern._compilec             C   s
   t | jƒS )N)r>   rR   )r(   r   r   r   Ú__str__»   s    zRegexPattern.__str__)NF)r   r&   r-   r9   r;   r)   rZ   r^   r\   r?   rd   r   r   r   r   r1   Š   s   
	r1   z/<(?:(?P<converter>[^>:]+):)?(?P<parameter>\w+)>Fc       
   
   C   s  | }dg}i }xìt  | ¡}|s0| t | ¡¡ P | t | d| ¡ … ¡¡ | | ¡ d… } | d¡}| ¡ s~t	d||f ƒ‚| d¡}|dkr”d}yt
|ƒ}W n2 tk
rÒ }	 zt	d||	f ƒ‚W dd}	~	X Y nX |||< | d| d	 |j d
 ¡ qW |�r| d¡ d |¡|fS )a  
    Convert a path pattern into a regular expression. Return the regular
    expression and a dictionary mapping the capture names to the converters.
    For example, 'foo/<int:pk>' returns '^foo\/(?P<pk>[0-9]+)'
    and {'pk': <django.urls.converters.IntConverter>}.
    ú^NÚ	parameterzLURL route '%s' uses parameter name %r which isn't a valid Python identifier.Ú	converterr>   z)URL route '%s' uses invalid converter %s.z(?P<ú>ú)r_   Ú )Ú_PATH_PARAMETER_COMPONENT_RErU   Úappendr`   ÚescapeÚstartrX   ÚgroupÚisidentifierr   r   ÚKeyErrorr;   r    )
ÚrouterT   Zoriginal_routeÚpartsr4   rZ   rf   Zraw_converterrg   rc   r   r   r   Ú_route_to_regexÄ   s8    


  
rt   c               @   s>   e Zd ZedƒZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚRoutePatternÚ_routeNFc             C   s0   || _ i | _|| _|| _tt|ƒ|ƒd | _d S )Nr   )rv   rA   rS   rH   rt   r>   r4   )r(   rr   rH   rT   r   r   r   r)   ï   s
    zRoutePattern.__init__c          	   C   sz   | j  |¡}|rv| ¡ }xF| ¡ D ]:\}}| j| }y| |¡||< W q" tk
rZ   d S X q"W || ¡ d … d|fS d S )Nr   )r;   rU   rV   Úitemsr4   Z	to_pythonÚ
ValueErrorrX   )r(   rY   rZ   r   ÚkeyÚvaluerg   r   r   r   rZ   ö   s    

zRoutePattern.matchc             C   sJ   |   ¡ }| j}d|ks*| d¡s*| d¡rF| td |  ¡ ¡dd�¡ |S )Nz(?P<re   r_   zŸYour URL pattern {} has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().z2_0.W001)rL   )rQ   rv   rM   rN   rl   r   rG   rJ   )r(   r]   rr   r   r   r   r^     s    
zRoutePattern.checkc             C   s   t  t|| jƒd ¡S )Nr   )r`   ra   rt   rS   )r(   rr   r   r   r   r?     s    zRoutePattern._compilec             C   s
   t | jƒS )N)r>   rv   )r(   r   r   r   rd     s    zRoutePattern.__str__)NF)
r   r&   r-   r9   r;   r)   rZ   r^   r?   rd   r   r   r   r   ru   ì   s   
ru   c               @   sN   e Zd Zddd„Zedd„ ƒZedd„ ƒZdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )ÚLocalePrefixPatternTc             C   s   || _ i | _d S )N)Úprefix_default_languager4   )r(   r|   r   r   r   r)     s    zLocalePrefixPattern.__init__c             C   s   t  | j¡S )N)r`   ra   Úlanguage_prefix)r(   r   r   r   r;     s    zLocalePrefixPattern.regexc             C   s,   t ƒ p
tj}|tjkr | js dS d| S d S )Nrj   z%s/)r   r   ZLANGUAGE_CODEr|   )r(   rD   r   r   r   r}   !  s    z#LocalePrefixPattern.language_prefixc             C   s*   | j }| |¡r&|t|ƒd … di fS d S )Nr   )r}   rM   Úlen)r(   rY   r}   r   r   r   rZ   )  s    
zLocalePrefixPattern.matchc             C   s   g S )Nr   )r(   r   r   r   r^   /  s    zLocalePrefixPattern.checkc             C   s
   d  | ¡S )Nz'{}')rG   )r(   r   r   r   rJ   2  s    zLocalePrefixPattern.describec             C   s   | j S )N)r}   )r(   r   r   r   rd   5  s    zLocalePrefixPattern.__str__N)T)r   r&   r-   r)   Úpropertyr;   r}   rZ   r^   rJ   rd   r   r   r   r   r{     s   
r{   c               @   sB   e Zd Zddd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zedd„ ƒZ	dS )Ú
URLPatternNc             C   s    || _ || _|pi | _|| _d S )N)r7   ÚcallbackÚdefault_argsrH   )r(   r7   r�   r‚   rH   r   r   r   r)   :  s    
zURLPattern.__init__c             C   s   d| j j| j ¡ f S )Nz<%s %s>)r%   r   r7   rJ   )r(   r   r   r   r,   @  s    zURLPattern.__repr__c             C   s   |   ¡ }| | j ¡ ¡ |S )N)Ú_check_pattern_namer[   r7   r^   )r(   r]   r   r   r   r^   C  s    zURLPattern.checkc             C   s>   | j jdk	r6d| j jkr6td | j  ¡ ¡dd�}|gS g S dS )zG
        Check that the pattern name does not contain a colon.
        Nr   zjYour URL pattern {} has a name including a ':'. Remove the colon, to avoid ambiguous namespace references.z	urls.W003)rL   )r7   rH   r   rG   rJ   )r(   rP   r   r   r   rƒ   H  s    
zURLPattern._check_pattern_namec             C   s>   | j  |¡}|r:|\}}}| | j¡ t| j||| j jƒS d S )N)r7   rZ   Úupdater‚   r   r�   rH   )r(   rY   rZ   Únew_pathr   r   r   r   r   ÚresolveV  s
    
zURLPattern.resolvec             C   sJ   | j }xt|tjƒr|j}qW t|dƒs:|jd |jj S |jd |j	 S )zw
        A string that identifies the view (e.g. 'path.to.view_function' or
        'path.to.ClassBasedView').
        r   r   )
r�   r=   Ú	functoolsÚpartialr   r$   r&   r%   r   r-   )r(   r�   r   r   r   Ú
lookup_str^  s    

zURLPattern.lookup_str)NN)
r   r&   r-   r)   r,   r^   rƒ   r†   r	   r‰   r   r   r   r   r€   9  s   
r€   c               @   s’   e Zd Zddd„Z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 )r0   Nc             C   sV   || _ || _d | _|pi | _|| _|| _i | _i | _i | _t	ƒ | _
d| _t ¡ | _d S )NF)r7   Úurlconf_namer�   Údefault_kwargsr#   r!   Ú_reverse_dictÚ_namespace_dictÚ	_app_dictÚsetÚ_callback_strsÚ
_populatedÚ	threadingÚlocalÚ_local)r(   r7   rŠ   r‹   r!   r#   r   r   r   r)   o  s    
zURLResolver.__init__c             C   sT   t | jtƒr*t| jƒr*d| jd jj }n
t| jƒ}d| jj|| j| j| j	 
¡ f S )Nz	<%s list>r   z<%s %s (%s:%s) %s>)r=   rŠ   Úlistr~   r%   r   Úreprr!   r#   r7   rJ   )r(   Zurlconf_reprr   r   r   r,   ‚  s    
zURLResolver.__repr__c             C   s4   g }x| j D ]}| t|ƒ¡ qW |s0| j ¡ }|S )N)r5   r[   r   r7   r^   )r(   r]   r7   r   r   r   r^   �  s    
zURLResolver.checkc             C   s(  t | jddƒrd S �zd| j_tƒ }i }i }tƒ }�x¼t| jƒD �]¬}|jjj}| 	d¡rf|dd … }t
|tƒrÐ| j |j¡ t|jjjƒ}| |j|||j|jjf¡ |jd k	rÎ| |j|||j|jjf¡ q@| ¡  |j�r| |jg ¡ |j¡ ||f||j< nÚx~|jD ]t}xl|j |¡D ]\\}	}
}}t||
 ƒ}t| jjf|jjŽ}t|f|Ž}| ||||
 t|f|jŽ|f¡ �q W �qW x,|j ¡ D ]\}\}}|| |f||< �q’W x*|j  ¡ D ]\}}| |g ¡ !|¡ �qÀW | j "|j¡ q@W || j#|< || j$|< || j%|< d| _&W d d| j_X d S )NÚ
populatingFTre   r   )'r<   r”   r—   r   r   Úreversedr5   r7   r;   rM   r=   r€   r�   Úaddr‰   r   Z
appendlistr�   r‚   r4   rH   Ú	_populater!   Ú
setdefaultrl   r#   Úreverse_dictÚgetlistr3   r‹   Únamespace_dictrw   Úapp_dictr[   r„   r�   rŽ   rŒ   r‘   )r(   Zlookupsr"   ZappsrD   Zurl_patternZ	p_patternÚbitsrH   ÚmatchesÚpatÚdefaultsr4   Znew_matchesZnew_convertersr#   ÚprefixZsub_patternr!   Znamespace_listr   r   r   rš   •  s^    







zURLResolver._populatec             C   s"   t ƒ }|| jkr|  ¡  | j| S )N)r   rŒ   rš   )r(   rD   r   r   r   rœ   Ò  s    
zURLResolver.reverse_dictc             C   s"   t ƒ }|| jkr|  ¡  | j| S )N)r   r�   rš   )r(   rD   r   r   r   rž   Ù  s    
zURLResolver.namespace_dictc             C   s"   t ƒ }|| jkr|  ¡  | j| S )N)r   rŽ   rš   )r(   rD   r   r   r   rŸ   à  s    
zURLResolver.app_dictc             C   s   | j s|  ¡  || jkS )N)r‘   rš   r�   )r(   rH   r   r   r   Ú_is_callbackç  s    zURLResolver._is_callbackc                s0  t |ƒ}g }| j |¡}|�r |\}}}xè| jD ]Þ‰ yˆ  |¡}W n` tk
r¢ } zB|jd  d¡}	|	d k	r†| ‡ fdd„|	D ƒ¡ n| 	ˆ g¡ W d d }~X Y q0X |�rt
|f| jŽ}
|
 |j¡ |j}|
sØ||j }t|j||
|j| jg|j | jg|j ƒS | 	ˆ g¡ q0W t||dœƒ‚td|iƒ‚d S )Nr   Útriedc             3   s   | ]}ˆ g| V  qd S )Nr   )r   Út)r7   r   r   ú	<genexpr>ø  s    z&URLResolver.resolve.<locals>.<genexpr>)r¦   rY   rY   )r>   r7   rZ   r5   r†   r   r   Úgetr[   rl   r3   r‹   r„   r   r   r   r   r!   r   r#   r"   )r(   rY   r¦   rZ   r…   r   r   Z	sub_matchrc   Z	sub_triedZsub_match_dictZsub_match_argsr   )r7   r   r†   ì  s:    

zURLResolver.resolvec             C   s    t | jtƒrt| jƒS | jS d S )N)r=   rŠ   r>   r   )r(   r   r   r   Úurlconf_module  s    
zURLResolver.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urlpatternsz§The 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.)rH   )r<   rª   ÚiterÚ	TypeErrorr   rG   rŠ   )r(   ÚpatternsÚmsgr   r   r   r5     s    zURLResolver.url_patternsc             C   s<   t | jd| d ƒ}|s0ddlm} t |d| ƒ}t|ƒi fS )Nz	handler%sr   )Úurls)r<   rª   r/   r¯   r   )r(   Z	view_typer�   r¯   r   r   r   Úresolve_error_handler(  s
    z!URLResolver.resolve_error_handlerc             O   s   | j |df|ž|ŽS )Nrj   )Ú_reverse_with_prefix)r(   Úlookup_viewr   r   r   r   r   Úreverse1  s    zURLResolver.reversec             O   s  |r|rt dƒ‚| js|  ¡  | j |¡}�xF|D �]<\}}}}	�x,|D �]"\}
}|rxt|ƒt|ƒkrhqHtt||ƒƒ}nPt|ƒ 	|¡ 
|¡rŽqHd}x*| ¡ D ]\}}| ||¡|krœd}P qœW |sÄqH|}i }x<| ¡ D ]0\}}||	krú|	|  |¡||< qÖt|ƒ||< qÖW | dd¡|
 }t dt |¡|f || ¡rHt|| td d�}| d	¡�rhd
|dd …  }|S qHW q2W t|dd ƒ}t|dd ƒ}|d k	�r®|d k	�r®d||f }n|}dd„ |D ƒ}|�r|�rØd|f }n|�rêd|f }nd}d||t|ƒ|f }ndd|i }t|ƒ‚d S )Nz2Don't mix *args and **kwargs in call to reverse()!TFú%z%%z^%s%sz/~:@)Úsafez//z/%%2F%sé   r&   r   z%s.%sc             S   s   g | ]\}}}}|‘qS r   r   )r   Ú_r7   r   r   r   r   k  s    z4URLResolver._reverse_with_prefix.<locals>.<listcomp>zarguments '%s'zkeyword arguments '%s'zno argumentsz;Reverse for '%s' with %s not found. %d pattern(s) tried: %szZReverse for '%(view)s' not found. '%(view)s' is not a valid view function or pattern name.Úview)rx   r‘   rš   rœ   r�   r~   r3   Úzipr�   Úsymmetric_differenceÚ
differencerw   r©   Zto_urlr>   Úreplacer`   rU   rm   r   r
   rM   r<   r   )r(   r²   Ú_prefixr   r   ÚpossibilitiesZpossibilityr7   r£   r4   ÚresultÚparamsZcandidate_subsr¡   ÚkÚvZtext_candidate_subsZcandidate_patÚurlÚmÚnZlookup_view_sr­   Zarg_msgr®   r   r   r   r±   4  sb    
z URLResolver._reverse_with_prefix)NNN)r   r&   r-   r)   r,   r^   rš   r   rœ   rž   rŸ   r¥   r†   r	   rª   r5   r°   r³   r±   r   r   r   r   r0   n  s   
=&	r0   )N)F)/Ú__doc__r‡   r`   r’   Ú	importlibr   Úurllib.parser   r/   r   Zdjango.core.checksr   Zdjango.core.checks.urlsr   Zdjango.core.exceptionsr   Zdjango.utils.datastructuresr   Zdjango.utils.functionalr	   Zdjango.utils.httpr
   Zdjango.utils.regex_helperr   Zdjango.utils.translationr   r4   r   Ú
exceptionsr   r   Úutilsr   r   Ú	lru_cacher2   r8   r9   rF   r1   ra   rk   rt   ru   r{   r€   r0   r   r   r   r   Ú<module>   s>   "
!5
(+"5