o
    uvXjsi  ã                   @   s’  d Z ddl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 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!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&ƒZ0G d'd(„ d(ƒZ1G d)d*„ d*ƒZ2d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)ÚErrorÚWarning)Úcheck_resolver)ÚImproperlyConfiguredÚViewDoesNotExist)ÚMultiValueDict)Úcached_property)ÚRFC3986_SUBDELIMSÚescape_leading_slashes)Ú	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¡| _|r+dd„ |D ƒng | _d | j¡| _	t
|dƒsF|jjd |jj | _n	|jd |j | _|pS| j}d | j|g ¡| _d S )Nc                 S   ó   g | ]}|r|‘qS © r   ©Ú.0Úxr   r   úR/var/www/html/myproject/venv/lib/python3.10/site-packages/django/urls/resolvers.pyÚ
<listcomp>(   ó    z*ResolverMatch.__init__.<locals>.<listcomp>ú:c                 S   r   r   r   r   r   r   r   r   *   r   Ú__name__Ú.)ÚfuncÚargsÚkwargsÚurl_nameÚrouteÚ	app_namesÚjoinÚapp_nameÚ
namespacesÚ	namespaceÚhasattrÚ	__class__Ú
__module__r   Ú
_func_pathÚ	view_name)	Úselfr!   r"   r#   r$   r&   r)   r%   Ú	view_pathr   r   r   Ú__init__   s   

zResolverMatch.__init__c                 C   s   | j | j| jf| S ©N)r!   r"   r#   )r0   Úindexr   r   r   Ú__getitem__7   s   zResolverMatch.__getitem__c                 C   s$   d| j | j| j| j| j| j| jf S )Nz^ResolverMatch(func=%s, args=%s, kwargs=%s, url_name=%s, app_names=%s, namespaces=%s, route=%s))r.   r"   r#   r$   r&   r)   r%   ©r0   r   r   r   Ú__repr__:   s   þzResolverMatch.__repr__)NNNN)r   r-   Ú__qualname__r2   r5   r7   r   r   r   r   r      s    
r   )Úmaxsizec                 C   s   | d u rt j} ttdƒ| ƒS ©Nú^/)r   ÚROOT_URLCONFÚURLResolverÚRegexPattern)Úurlconfr   r   r   Úget_resolverA   s   r@   c                 C   s.   t | ƒ}t|ƒ|_t||jƒ}tt dƒ|gƒS r:   )r>   ÚdictÚ
convertersr=   Úurl_patterns)Ú
ns_patternÚresolverrB   ÚpatternÚns_resolverr   r   r   Úget_ns_resolverH   s   
rH   c                   @   s   e Zd Zdd„ Zddd„ZdS )ÚLocaleRegexDescriptorc                 C   s
   || _ d S r3   )Úattr)r0   rJ   r   r   r   r2   T   ó   
zLocaleRegexDescriptor.__init__Nc                 C   sj   |du r| S t || jƒ}t|tƒr| |¡|jd< |jd S tƒ }||jvr0| t|ƒ¡|j|< |j| S )zT
        Return a compiled regular expression based on the active language.
        NÚregex)ÚgetattrrJ   Ú
isinstanceÚstrÚ_compileÚ__dict__r   Ú_regex_dict)r0   ÚinstanceÚclsrF   Úlanguage_coder   r   r   Ú__get__W   s   



zLocaleRegexDescriptor.__get__r3   )r   r-   r8   r2   rV   r   r   r   r   rI   S   s    rI   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 [name='{}'])ÚformatÚname)r0   Údescriptionr   r   r   Údescribek   s   
zCheckURLMixin.describec                 C   sF   | j j}tjs	g S | d¡r!| d¡s!td |  ¡ ¡dd�}|gS g S )zM
        Check that the pattern does not begin with a forward slash.
        )ú/r;   z^\/r]   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©Úid)	rL   rF   r   ÚAPPEND_SLASHÚ
startswithÚendswithr   rY   r\   )r0   Úregex_patternÚwarningr   r   r   Ú_check_pattern_startswith_slasht   s   ÿúz-CheckURLMixin._check_pattern_startswith_slashN)r   r-   r8   r\   re   r   r   r   r   rW   j   s    	rW   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 )r>   Ú_regexNFc                 C   s"   || _ i | _|| _|| _i | _d S r3   )rf   rR   Ú_is_endpointrZ   rB   )r0   rL   rZ   Úis_endpointr   r   r   r2   Ž   s
   
zRegexPattern.__init__c                 C   sB   | j  |¡}|r| ¡ }|rdn| ¡ }|| ¡ d … ||fS d S ©Nr   )rL   ÚsearchÚ	groupdictÚgroupsÚend)r0   ÚpathÚmatchr#   r"   r   r   r   ro   •   s   zRegexPattern.matchc                 C   s*   g }|  |  ¡ ¡ | js|  |  ¡ ¡ |S r3   )Úextendre   rg   Ú_check_include_trailing_dollar©r0   Úwarningsr   r   r   Úcheck    s
   zRegexPattern.checkc                 C   s8   | j j}| d¡r| d¡std |  ¡ ¡dd�gS g 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.W001r^   )rL   rF   rb   r   rY   r\   )r0   rc   r   r   r   rq   §   s   
üz+RegexPattern._check_include_trailing_dollarc              
   C   s8   zt  |¡W S  t jy } ztd||f ƒ‚d}~ww )z0Compile and return the given regular expression.z*"%s" is not a valid regular expression: %sN)ÚreÚcompileÚerrorr   )r0   rL   Úer   r   r   rP   ³   s   
ÿ€ÿzRegexPattern._compilec                 C   ó
   t | jƒS r3   )rO   rf   r6   r   r   r   Ú__str__¼   rK   zRegexPattern.__str__©NF)r   r-   r8   rI   rL   r2   ro   rt   rq   rP   r{   r   r   r   r   r>   ‹   s    
	r>   z/<(?:(?P<converter>[^>:]+):)?(?P<parameter>\w+)>Fc           
   
   C   s  | }dg}i }	 t  | ¡}|s| t | ¡¡ n`| t | d| ¡ … ¡¡ | | ¡ d… } | d¡}| ¡ s?t	d||f ƒ‚| d¡}|du rJd}zt
|ƒ}W n tyd }	 zt	d||	f ƒ‚d}	~	ww |||< | d	| d
 |j d ¡ q|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>}.
    ú^TNÚ	parameterzLURL route '%s' uses parameter name %r which isn't a valid Python identifier.Ú	converterrO   z)URL route '%s' uses invalid converter %s.ú(?P<ú>ú)ru   Ú )Ú_PATH_PARAMETER_COMPONENT_RErj   Úappendrv   ÚescapeÚstartrm   ÚgroupÚisidentifierr   r   ÚKeyErrorrL   r'   )
r%   rh   Úoriginal_routeÚpartsrB   ro   r~   Úraw_converterr   ry   r   r   r   Ú_route_to_regexÅ   sD   

ÿÿ

ÿ€ÿè
rŽ   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   )r�   rR   rg   rZ   rŽ   rO   rB   )r0   r%   rZ   rh   r   r   r   r2   ð   s
   zRoutePattern.__init__c              	   C   sv   | j  |¡}|r9| ¡ }| ¡ D ]\}}| j| }z	| |¡||< W q ty-   Y  d S w || ¡ d … d|fS d S ri   )rL   rj   rk   ÚitemsrB   Ú	to_pythonÚ
ValueErrorrm   )r0   rn   ro   r#   ÚkeyÚvaluer   r   r   r   ro   ÷   s   
ÿzRoutePattern.matchc                 C   sJ   |   ¡ }| j}d|v s| d¡s| d¡r#| td |  ¡ ¡dd�¡ |S )Nr€   r}   ru   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.W001r^   )re   r�   ra   rb   r…   r   rY   r\   )r0   rs   r%   r   r   r   rt     s   
üzRoutePattern.checkc                 C   s   t  t|| jƒd ¡S )Nr   )rv   rw   rŽ   rg   )r0   r%   r   r   r   rP     ó   zRoutePattern._compilec                 C   rz   r3   )rO   r�   r6   r   r   r   r{     rK   zRoutePattern.__str__r|   )
r   r-   r8   rI   rL   r2   ro   rt   rP   r{   r   r   r   r   r�   í   s    
r�   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 r3   )Úprefix_default_languagerB   )r0   r˜   r   r   r   r2     s   
zLocalePrefixPattern.__init__c                 C   s   t  | j¡S r3   )rv   rw   Úlanguage_prefixr6   r   r   r   rL     s   zLocalePrefixPattern.regexc                 C   s(   t ƒ ptj}|tjkr| jsdS d| S )Nrƒ   z%s/)r   r   ÚLANGUAGE_CODEr˜   ©r0   rU   r   r   r   r™   "  s   z#LocalePrefixPattern.language_prefixc                 C   s*   | j }| |¡r|t|ƒd … di fS d S ri   )r™   ra   Úlen)r0   rn   r™   r   r   r   ro   *  s   
zLocalePrefixPattern.matchc                 C   s   g S r3   r   r6   r   r   r   rt   0  s   zLocalePrefixPattern.checkc                 C   s
   d  | ¡S )NrX   )rY   r6   r   r   r   r\   3  rK   zLocalePrefixPattern.describec                 C   s   | j S r3   )r™   r6   r   r   r   r{   6  s   zLocalePrefixPattern.__str__N)T)r   r-   r8   r2   ÚpropertyrL   r™   ro   rt   r\   r{   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 r3   )rF   ÚcallbackÚdefault_argsrZ   )r0   rF   rŸ   r    rZ   r   r   r   r2   ;  s   

zURLPattern.__init__c                 C   s   d| j j| j ¡ f S )Nz<%s %s>)r,   r   rF   r\   r6   r   r   r   r7   A  r–   zURLPattern.__repr__c                 C   s   |   ¡ }| | j ¡ ¡ |S r3   )Ú_check_pattern_namerp   rF   rt   rr   r   r   r   rt   D  s   zURLPattern.checkc                 C   s:   | j jdurd| j jv rtd | j  ¡ ¡dd�}|gS g 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.W003r^   )rF   rZ   r   rY   r\   )r0   rd   r   r   r   r¡   I  s   ýzURLPattern._check_pattern_namec                 C   sH   | j  |¡}|r"|\}}}| | j¡ t| j||| j jt| j ƒd�S d S )N)r%   )rF   ro   Úupdater    r   rŸ   rZ   rO   )r0   rn   ro   Únew_pathr"   r#   r   r   r   ÚresolveW  s   
üzURLPattern.resolvec                 C   sD   | j }t|tjƒr|j}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Ÿ   rN   Ú	functoolsÚpartialr!   r+   r-   r,   r   r8   )r0   rŸ   r   r   r   Ú
lookup_str_  s   
zURLPattern.lookup_str)NN)
r   r-   r8   r2   r7   rt   r¡   r¤   r   r§   r   r   r   r   rž   :  s    
rž   c                   @   s¦   e Zd Zd"dd„Zdd„ Zdd„ Zdd	„ Zd
d„ Ze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 )#r=   Nc                 C   sV   || _ || _d | _|pi | _|| _|| _i | _i | _i | _t	ƒ | _
d| _t ¡ | _d S r|   )rF   Úurlconf_namerŸ   Údefault_kwargsr*   r(   Ú_reverse_dictÚ_namespace_dictÚ	_app_dictÚsetÚ_callback_strsÚ
_populatedÚ	threadingÚlocalÚ_local)r0   rF   r¨   r©   r(   r*   r   r   r   r2   n  s   
zURLResolver.__init__c                 C   sP   t | jtƒr| 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>)
rN   r¨   Úlistr,   r   Úreprr(   r*   rF   r\   )r0   Úurlconf_reprr   r   r   r7   �  s   
þzURLResolver.__repr__c                 C   s:   g }| j D ]	}| t|ƒ¡ q| |  ¡ ¡ |p| j ¡ S r3   )rC   rp   r   Ú_check_custom_error_handlersrF   rt   )r0   ÚmessagesrF   r   r   r   rt   Œ  s
   
zURLResolver.checkc                 C   sö   g }dD ]t\}}z	|   |¡\}}W n/ ttfy@ } z!t| jd| ƒ}dj||d�}| t|t|ƒdd�¡ W Y d }~qd }~ww t	 
|¡}	d g| }
z|	j|
Ž  W q tyx   dj||jd |j |d	krid
ndd�}| t|dd�¡ Y qw |S )N))i�  é   )i“  r¸   )i”  r¸   )iô  r   ú	handler%szDThe custom handler{status_code} view '{path}' could not be imported.)Ústatus_codern   z	urls.E008)Úhintr_   zeThe custom handler{status_code} view '{path}' does not take the correct number of arguments ({args}).r    r¸   zrequest, exceptionÚrequest)rº   rn   r"   z	urls.E007r^   )Úresolve_error_handlerÚImportErrorr	   rM   Úurlconf_modulerY   r…   r   rO   ÚinspectÚ	signatureÚbindÚ	TypeErrorr-   r8   )r0   r·   rº   Únum_parametersÚhandlerÚ
param_dictry   rn   ÚmsgrÁ   r"   r   r   r   r¶   “  s6   þ€ú

ú÷
z(URLResolver._check_custom_error_handlersc                 C   s  t | jddƒr	d S zûd| j_tƒ }i }i }tƒ }t| jƒD ]Î}|jjj}| 	d¡r/|dd … }t
|tƒrd| j |j¡ t|jjjƒ}| |j|||j|jjf¡ |jd urc| |j|||j|jjf¡ q| ¡  |jr~| |jg ¡ |j¡ ||f||j< nf|jD ]0}|j |¡D ]'\}	}
}}t||
 ƒ}| ||||
 i |¥|j¥i | jj¥|jj¥|¥f¡ q‰q�|j ¡ D ]\}\}}|jj}|jj |¡ || |f||< q·|j  ¡ D ]\}}| |g ¡ !|¡ qÖ| j |j¡ q|| j"|< || j#|< || j$|< d| _%W d| j_d S d| j_w )NÚ
populatingFTr}   r   )&rM   r²   rÈ   r
   r   ÚreversedrC   rF   rL   ra   rN   rž   r®   Úaddr§   r   Ú
appendlistrŸ   r    rB   rZ   Ú	_populater(   Ú
setdefaultr…   r*   Úreverse_dictÚgetlistr©   Únamespace_dictr‘   r¢   Úapp_dictrp   r«   r¬   rª   r¯   )r0   Úlookupsr)   ÚappsrU   Úurl_patternÚ	p_patternÚbitsrZ   ÚmatchesÚpatÚdefaultsrB   Únew_matchesr*   ÚprefixÚsub_patternÚcurrent_convertersr(   Únamespace_listr   r   r   rÌ   ±  sj   


þ
þ€
üþþ


zURLResolver._populatec                 C   ó"   t ƒ }|| jvr|  ¡  | j| S r3   )r   rª   rÌ   r›   r   r   r   rÎ   î  ó   

zURLResolver.reverse_dictc                 C   rß   r3   )r   r«   rÌ   r›   r   r   r   rÐ   õ  rà   zURLResolver.namespace_dictc                 C   rß   r3   )r   r¬   rÌ   r›   r   r   r   rÑ   ü  rà   zURLResolver.app_dictc                 C   s&   | s|S |  d¡r|dd… }| | S )z<Join two routes, without the starting ^ in the second route.r}   r   N)ra   )Úroute1Úroute2r   r   r   Ú_join_route  s
   
zURLResolver._join_routec                 C   s   | j s|  ¡  || jv S r3   )r¯   rÌ   r®   )r0   rZ   r   r   r   Ú_is_callback  s   
zURLResolver._is_callbackc                    sN  t |ƒ}g }| j |¡}|r¡|\}}}| jD ]ƒ‰ zˆ  |¡}W n1 tyP } z%|jd  d¡}	|	d ur@| ‡ fdd„|	D ƒ¡ n| 	ˆ g¡ W Y d }~qd }~ww |r“i |¥| j
¥}
|
 |j¡ |j}|
sj||j }tˆ tƒrqdnt ˆ jƒ}t|j||
|j| jg|j | jg|j |  ||j¡ƒ  S | 	ˆ g¡ qt||dœƒ‚td|iƒ‚)Nr   Útriedc                 3   s   � | ]}ˆ g| V  qd S r3   r   )r   Út©rF   r   r   Ú	<genexpr>  s   € z&URLResolver.resolve.<locals>.<genexpr>rƒ   )rå   rn   rn   )rO   rF   ro   rC   r¤   r   r"   Úgetrp   r…   r©   r¢   r#   rN   rž   r   r!   r$   r(   r&   r*   r)   rã   r%   )r0   rn   rå   ro   r£   r"   r#   Ú	sub_matchry   Ú	sub_triedÚsub_match_dictÚsub_match_argsÚcurrent_router   rç   r   r¤     sD   

€û
ù	zURLResolver.resolvec                 C   s   t | jtƒrt| jƒS | jS r3   )rN   r¨   rO   r   r6   r   r   r   r¿   9  s   
zURLResolver.urlconf_modulec                 C   sD   t | jd| jƒ}zt|ƒ W |S  ty!   d}t|j| jd�ƒ‚w )NÚ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.)rZ   )rM   r¿   ÚiterrÃ   r   rY   r¨   )r0   ÚpatternsrÇ   r   r   r   rC   @  s   
ùÿúzURLResolver.url_patternsc                 C   s<   t | jd| d ƒ}|sddlm} t |d| ƒ}t|ƒi fS )Nr¹   r   )Úurls)rM   r¿   Údjango.confrò   r   )r0   Ú	view_typerŸ   rò   r   r   r   r½   O  s
   z!URLResolver.resolve_error_handlerc                 O   s   | j |dg|¢R i |¤ŽS )Nrƒ   )Ú_reverse_with_prefix)r0   Úlookup_viewr"   r#   r   r   r   ÚreverseX  s   zURLResolver.reversec                    sÖ  |rˆ rt dƒ‚| js|  ¡  | j |¡}|D ]ƒ\}}}}	|D ]z\}
}|r6t|ƒt|ƒkr.qtt||ƒƒ}ntˆ ƒ 	|¡ 
|¡rAqt‡ fdd„| ¡ D ƒƒrOqˆ }i }| ¡ D ]\}}||	v ri|	|  |¡||< qWt|ƒ||< qW| dd¡|
 }t dt |¡|f || ¡r™t|| td d�}t|ƒ    S qqt|d	d ƒ}t|d
d ƒ}|d ur¶|d ur¶d||f }n|}dd„ |D ƒ}|rá|rÉd|f }n
ˆ rÑdˆ f }nd}d||t|ƒ|f }t|ƒ‚dd|i }t|ƒ‚)Nz2Don't mix *args and **kwargs in call to reverse()!c                 3   s$   � | ]\}}ˆ   ||¡|kV  qd S r3   )ré   )r   ÚkÚv©r#   r   r   rè   m  s   €" z3URLResolver._reverse_with_prefix.<locals>.<genexpr>ú%z%%z^%s%sz/~:@)Úsafer-   r   z%s.%sc                 S   s   g | ]\}}}}|‘qS r   r   )r   Ú_rF   r   r   r   r   ‹  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)r“   r¯   rÌ   rÎ   rÏ   rœ   rA   Úzipr­   Úsymmetric_differenceÚ
differenceÚanyr‘   Úto_urlrO   Úreplacerv   rj   r†   r   r   r   rM   r   )r0   rö   Ú_prefixr"   r#   ÚpossibilitiesÚpossibilityrF   rÙ   rB   ÚresultÚparamsÚcandidate_subsÚtext_candidate_subsrø   rù   Úcandidate_patÚurlÚmÚnÚlookup_view_srñ   Úarg_msgrÇ   r   rú   r   rõ   [  sb   üèÿÿ	ýÿÿz URLResolver._reverse_with_prefix)NNN)r   r-   r8   r2   r7   rt   r¶   rÌ   r�   rÎ   rÐ   rÑ   Ústaticmethodrã   rä   r¤   r   r¿   rC   r½   r÷   rõ   r   r   r   r   r=   m  s.    
=



(

	r=   r3   )F)3Ú__doc__r¥   rÀ   rv   r°   Ú	importlibr   Úurllib.parser   ró   r   Údjango.core.checksr   r   Údjango.core.checks.urlsr   Údjango.core.exceptionsr   r	   Údjango.utils.datastructuresr
   Údjango.utils.functionalr   Údjango.utils.httpr   r   Údjango.utils.regex_helperr   Údjango.utils.translationr   rB   r   Ú
exceptionsr   r   Úutilsr   r   Ú	lru_cacher@   rH   rI   rW   r>   rw   r„   rŽ   r�   r—   rž   r=   r   r   r   r   Ú<module>   sF    
#


!5ÿ
(+"3