

_V_g                 @   s  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 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 m Z d d l m Z 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( m) Z) e	   Z* e	   Z+ Gd d   d e,  Z- Gd d   d e  Z. Gd d   d e/  Z0 e j d d  d d d   Z1 e j d d  d d d   Z2 e j d d  d d    Z3 d  d!   Z4 Gd" d#   d# e,  Z5 Gd$ d%   d% e5  Z6 Gd& d'   d' e5  Z7 Gd( d)   d) e7  Z8 d d* d+  Z9 d d d d d, d-  Z: e e: e j;  Z< d. d/   Z= d0 d1   Z> d2 d3   Z? d4 d5   Z@ d6 d7   ZA d d8 d9  ZB d d: d;  ZC d< d=   ZD 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)local)ImproperlyConfiguredViewDoesNotExist)Http404)	lru_cachesix)MultiValueDict)RemovedInDjango110Warning)	force_str
force_text
iri_to_uri)cached_propertylazy)RFC3986_SUBDELIMSurlquote)module_has_submodule)	normalize)urlsplit
urlunsplit)get_languageoverridec               @   s=   e  Z d  Z d d d d d  Z d d   Z d d   Z d S)ResolverMatchNc             C   s  | |  _  | |  _ | |  _ | |  _ | r= d d   | D n g  |  _ d j |  j  |  _ | rz d d   | D |  _ n	 g  |  _ d j |  j  |  _ t	 | d  s d 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   :/tmp/pip-build-ghmbqnp_/Django/django/core/urlresolvers.py
<listcomp>/   s   	 z*ResolverMatch.__init__.<locals>.<listcomp>:c             S   s   g  |  ] } | r |  q Sr   r   )r   r   r   r   r   r   3   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__B   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__E   s    zResolverMatch.__repr__)r    r-   __qualname__r0   r2   r3   r   r   r   r   r   &   s   r   c               @   s   e  Z d  Z d S)Resolver404N)r    r-   r4   r   r   r   r   r5   J   s   r5   c               @   s   e  Z d  Z d S)NoReverseMatchN)r    r-   r4   r   r   r   r   r6   N   s   r6   maxsizeFc             C   sX  t  |   r |  St |  t j  s5 t d |    n  t |   \ } } | sj | rW |  St d |    n  y t |  } Wnf t k
 r | r |  St |  \ } } | r t t |  |  r t d |  | f   n   Ynr Xy t	 | |  } Wn2 t
 k
 r*| r|  St d |  | f   Yn* Xt  |  sPt d | | f   n  | Sd S)a  
    Return a callable corresponding to lookup_view. This function is used
    by both resolve() and reverse(), so can_fail allows the caller to choose
    between returning the input as is and raising an exception when the input
    string can't be interpreted as an import path.

    If lookup_view is already a callable, return it.
    If lookup_view is a string import path that can be resolved to a callable,
      import that callable and return it.
    If lookup_view is some other kind of string and can_fail is True, the string
      is returned as is. If can_fail is False, an exception is raised (either
      ImportError or ViewDoesNotExist).
    z-'%s' is not a callable or a dot-notation pathz8Could not import '%s'. The path must be fully qualified.z7Could not import '%s'. Parent module %s does not exist.z8Could not import '%s'. View does not exist in module %s.z/Could not import '%s.%s'. View is not callable.N)callable
isinstancer	   string_typesr   get_mod_funcImportErrorr   r   getattrAttributeError)lookup_viewZcan_failZmod_name	func_namemodZ	parentmodZsubmodZ	view_funcr   r   r   get_callableR   sH    rB   c             C   s5   |  d  k r( d d l  m } | j }  n  t d |   S)Nr   )settingsz^/)django.confrC   ZROOT_URLCONFRegexURLResolver)urlconfrC   r   r   r   get_resolver   s    rG   c             C   s"   t  |  | j  } t  d | g  S)Nz^/)rE   url_patterns)
ns_patternresolverZns_resolverr   r   r   get_ns_resolver   s    rK   c             C   sT   y |  j  d  } Wn t k
 r1 |  d f SYn X|  d  |  |  | d d   f S)Nr!       )rindex
ValueError)callbackdotr   r   r   r;      s
    r;   c               @   s4   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   r0      s    	zLocaleRegexProvider.__init__c             C   s   t    } | |  j k r t |  j t j  r9 |  j } n t |  j  } y t j | t j	  } WnG t j
 k
 r } z$ t d | t j |  f   WYd d } ~ Xn X| |  j | <n  |  j | S)zl
        Returns a compiled regular expression, depending upon the activated
        language-code.
        z*"%s" is not a valid regular expression: %sN)r   rT   r9   rS   r	   r:   r   recompileUNICODEerrorr   	text_type)r/   language_coderU   Zcompiled_regexer   r   r   rU      s    	,zLocaleRegexProvider.regexN)r    r-   r4   __doc__r0   propertyrU   r   r   r   r   rR      s   rR   c               @   sX   e  Z d  Z d d d d  Z d d   Z d d   Z d d	   Z e d
 d    Z d S)RegexURLPatternNc             C   sV   t  j |  |  t |  r( | |  _ n d  |  _ | |  _ | pC i  |  _ | |  _ d  S)N)rR   r0   r8   	_callback_callback_strdefault_argsname)r/   rU   rP   rb   rc   r   r   r   r0      s    		zRegexURLPattern.__init__c             C   s&   t  d |  j j |  j |  j j f  S)Nz
<%s %s %s>)r   r,   r    rc   rU   pattern)r/   r   r   r   r3      s    zRegexURLPattern.__repr__c             C   s3   | s t  |  d  r d S| d |  j |  _ d S)zD
        Adds the prefix string to a string-based callback.
        ra   Nr!   )r+   ra   )r/   prefixr   r   r   
add_prefix   s    zRegexURLPattern.add_prefixc             C   sl   |  j  j |  } | rh | j   } | r3 f  } n | j   } | j |  j  t |  j | | |  j  Sd  S)N)	rU   search	groupdictgroupsupdaterb   r   rP   rc   )r/   pathmatchr$   r#   r   r   r   resolve   s    	zRegexURLPattern.resolvec             C   s/   |  j  d  k	 r |  j  St |  j  |  _  |  j  S)N)r`   rB   ra   )r/   r   r   r   rP      s    zRegexURLPattern.callback)	r    r-   r4   r0   r3   rf   rm   r^   rP   r   r   r   r   r_      s
   r_   c               @   s   e  Z d  Z d d 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)rE   Nc             C   sw   t  j |  |  | |  _ d  |  _ | p+ i  |  _ | |  _ | |  _ i  |  _ i  |  _ i  |  _	 t
   |  _ d |  _ d  S)NF)rR   r0   urlconf_namerP   default_kwargsr*   r(   _reverse_dict_namespace_dict	_app_dictset_callback_strs
_populated)r/   rU   rn   ro   r(   r*   r   r   r   r0     s    							zRegexURLResolver.__init__c             C   sy   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>)r9   rn   listlenr,   r    reprstrr(   r*   rU   rd   )r/   Zurlconf_reprr   r   r   r3     s    !	zRegexURLResolver.__repr__c          
   C   s  t    } i  } i  } t   } xt |  j  D]} t | d  rY |  j j | j  n t | d  r | j } t	 | t
 j  r | j } n  t | d  s | j d | j j } n | j d | j } |  j j |  n  | j j } | j d  r| d d   } n  t	 | t  rn| j rf| | f | | j <| j rk| j | j g   j | j  qkq| j j }	 xp | j D]e }
 x\ | j j |
  D]H \ } } } t |	 |  } | j |
 | | | t | | j  f  qWq|Wx7 | j j   D]& \ } \ } } | | | f | | <qWx6 | j  j   D]% \ } } | j | g   j! |  q/W|  j j" | j  q. t |  } | j | j# | | | j$ f  | j% d  k	 r. | j | j% | | | j$ f  q. q. W| |  j& | <| |  j' | <| |  j( | <d |  _) d  S)Nra   r`   r    r!   ^rM   T)*r
   r   reversedrH   r+   rt   addra   r`   r9   	functoolspartialr"   r-   r,   r    rU   rd   
startswithrE   r*   r(   
setdefaultappendreverse_dictgetlistr   Z
appendlistdictro   namespace_dictitemsapp_dictextendrj   rP   rb   rc   rp   rq   rr   ru   )r/   Zlookupsr)   Zappsr[   rd   rP   Z
lookup_strZ	p_patternZ
parent_patrc   matchespatdefaultsZnew_matchesr*   re   Zsub_patternr(   Znamespace_listbitsr   r   r   	_populate   sZ    					%""&zRegexURLResolver._populatec             C   s0   t    } | |  j k r% |  j   n  |  j | S)N)r   rp   r   )r/   r[   r   r   r   r   V  s    	zRegexURLResolver.reverse_dictc             C   s0   t    } | |  j k r% |  j   n  |  j | S)N)r   rq   r   )r/   r[   r   r   r   r   ]  s    	zRegexURLResolver.namespace_dictc             C   s0   t    } | |  j k r% |  j   n  |  j | S)N)r   rr   r   )r/   r[   r   r   r   r   d  s    	zRegexURLResolver.app_dictc             C   s#   |  j  s |  j   n  | |  j k S)N)ru   r   rt   )r/   rc   r   r   r   _is_callbackk  s    	zRegexURLResolver._is_callbackc       
         s  t  |  } g  } |  j j |  } | r| | j   d   } x=|  j D]2  y   j |  } Wnz t k
 r } zZ | j d j d  } | d  k	 r | j	   f d d   | D  n | j
   g  WYd  d  } ~ XqJ X| rlt | j   |  j  } | j | j  | j }	 | s3| j   | j }	 n  t | j |	 | | j |  j g | j |  j g | j  S| j
   g  qJ Wt i | d 6| d 6  n  t i | d 6  d  S)Nr   triedc             3   s   |  ] }   g | Vq d  S)Nr   )r   t)rd   r   r   	<genexpr>|  s    z+RegexURLResolver.resolve.<locals>.<genexpr>rk   )r   rU   rg   endrH   rm   r5   r#   getr   r   r   rh   ro   rj   r$   ri   r   r"   r%   r(   r&   r*   r)   )
r/   rk   r   rl   new_pathZ	sub_matchr\   Z	sub_triedZsub_match_dictZsub_match_argsr   )rd   r   rm   p  s:    ##	zRegexURLResolver.resolvec             C   s-   t  |  j t j  r" t |  j  S|  j Sd  S)N)r9   rn   r	   r:   r   )r/   r   r   r   urlconf_module  s    zRegexURLResolver.urlconf_modulec             C   s`   t  |  j d |  j  } y t |  Wn3 t k
 r[ d } t | j d |  j    Yn 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.rc   )r=   r   iter	TypeErrorr   formatrn   )r/   patternsmsgr   r   r   rH     s     zRegexURLResolver.url_patternsc             C   sU   t  |  j d | d   } | sE d d l m } t  | d |  } n  t |  i  f S)Nz	handler%sr   )urls)r=   r   rD   r   rB   )r/   Z	view_typerP   r   r   r   r   resolve_error_handler  s
    z&RegexURLResolver.resolve_error_handlerc             O   s   |  j  | d | |  S)NrL   )_reverse_with_prefix)r/   r?   r#   r$   r   r   r   reverse  s    zRegexURLResolver.reversec             O   s<  | r | r t  d   n  d d   | D } d d   | j   D } |  j s] |  j   n  | } y% |  j |  r t | d  } n  WnA t t f k
 r } z t d | | f   WYd  d  } ~ Xn7 Xt	 |  rt	 |  rt
 j d | t d	 d
 n  |  j j |  }	 x|	 D]\ }
 } } xz|
 D]r\ } } | ryt |  t |  k raq1n  t t | |   } n t | j    t | j    Bt |  t | j    Bk rq1n  d } x< | j   D]. \ } } | j | |  | k rd } PqqW| sq1n  | } | j d d  | } t j d t j |  | f | | t j  r1t | | d t t d  } | j d  rd | d d   } n  | Sq1WqWt | d d   } t | d d   } | d  k	 r| d  k	 rd | | 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 Sr   )r   )r   vr   r   r   r     s   	 z9RegexURLResolver._reverse_with_prefix.<locals>.<listcomp>c             S   s%   i  |  ] \ } } t  |  |  q Sr   )r   )r   kr   r   r   r   
<dictcomp>  s   	 z9RegexURLResolver._reverse_with_prefix.<locals>.<dictcomp>TzError importing '%s': %s.z,Reversing by dotted path is deprecated (%s).
stacklevel   F%z%%z^%s%ssafez/~:@z//z/%%2F%s   r-   r    z%s.%sc             S   s   g  |  ] \ } } } |  q Sr   r   )r   possibilityrd   r   r   r   r   r     s   	 zbReverse for '%s' with arguments '%s' and keyword arguments '%s' not found. %d pattern(s) tried: %s)rO   r   ru   r   r   rB   r<   r>   r6   r8   warningswarnr   r   r   rw   r   ziprs   keysr   replacerV   rg   escaperX   r   r   ry   r   r=   )r/   r?   _prefixr#   r$   Z	text_argsZtext_kwargsZoriginal_lookupr\   possibilitiesr   rd   r   resultparamsZcandidate_subsr   r   r   Zcandidate_paturlmnZlookup_view_sr   r   r   r   r     s`    	)(/ z%RegexURLResolver._reverse_with_prefix)r    r-   r4   r0   r3   r   r^   r   r   r   r   rm   r   r   rH   r   r   r   r   r   r   r   rE     s   
6'	rE   c                   sC   e  Z d  Z d Z d d d   f d d  Z e d d    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.
    Nc                s&   t  t |   j d  | | | |  d  S)N)superr   r0   )r/   rn   ro   r(   r*   )r,   r   r   r0     s    zLocaleRegexURLResolver.__init__c             C   sL   t    } | |  j k rA t j d | t j  } | |  j | <n  |  j | S)Nz^%s/)r   rT   rV   rW   rX   )r/   r[   Zregex_compiledr   r   r   rU   
  s
    	zLocaleRegexURLResolver.regex)r    r-   r4   r]   r0   r^   rU   r   r   )r,   r   r     s   r   c             C   s+   | d  k r t    } n  t |  j |   S)N)get_urlconfrG   rm   )rk   rF   r   r   r   rm     s    rm   c             C   s/  | d  k r t    } n  t |  } | p- g  } | p9 i  } t   } t |  t j  s` |  } n|  j d  } | j   | d } | d d   }	 | r | j d  }
 |
 j   n d  }
 g  } d } x+|	 r|	 j   } |
 r |
 j   n d  } yE | j	 | } | r| | k r| } n | | k r8| d } n  Wn t
 k
 rMYn X| | k rcd  }
 n  y. | j | \ } } | j |  | | } Wq t
 k
 r} z= | rt d | d j |  f   n t d |   WYd  d  } ~ Xq Xq W| rt | |  } n  t t | j | | | |    S)Nr   r   rM   rL   z,%s is not a registered namespace inside '%s'z %s is not a registered namespace)r   rG   get_script_prefixr9   r	   r:   splitr   popr   KeyErrorr   r   r6   r'   rK   r   r   r   )ZviewnamerF   r#   r$   Zcurrent_apprJ   re   Zviewpartsrk   Zcurrent_pathZresolved_pathrI   nsZ
current_nsZapp_listextrakeyr   r   r   r     sZ    		

			!r   c               C   s"   t  j   t j   t j   d  S)N)rB   cache_clearrG   rK   r   r   r   r   clear_url_caches]  s    

r   c             C   s)   |  j  d  s |  d 7}  n  |  t _ d S)z8
    Sets the script prefix for the current thread.
    /N)endswith	_prefixesvalue)re   r   r   r   set_script_prefixc  s    r   c               C   s   t  t d d  S)z
    Returns the currently active script prefix. Useful for client code that
    wishes to construct their own URLs manually (although accessing the request
    instance is normally going to be a lot cleaner).
    r   r   )r=   r   r   r   r   r   r   l  s    r   c               C   s#   y
 t  ` Wn t k
 r Yn Xd S)z:
    Unsets the script prefix for the current thread.
    N)r   r   r>   r   r   r   r   clear_script_prefixu  s    
r   c             C   s.   |  r |  t  _ n t t  d  r* t  ` n  d S)z
    Sets the URLconf for the current thread (overriding the default one in
    settings). Set to None to revert back to the default.
    r   N)	_urlconfsr   r+   )rn   r   r   r   set_urlconf  s    r   c             C   s   t  t d |   S)zq
    Returns the root URLconf to use for the current thread if it has been
    changed from the default one.
    r   )r=   r   )defaultr   r   r   r     s    r   c             C   s2   y t  |  |  d SWn t k
 r- d SYn Xd S)z
    Returns True if the given path resolves against the default URL resolver,
    False otherwise.

    This is a convenience method to make working with "is this a match?" cases
    easier, avoiding unnecessarily indented try...except blocks.
    TFN)rm   r5   )rk   rF   r   r   r   is_valid_path  s
    r   c             C   s   t  |   } y t | j  } Wn t k
 r3 Yn X| j rS d | j | j f n | j } t |  c y" t | d | j d | j	 }  Wn t
 k
 r Yn( Xt | j | j |  | j | j f  }  Wd QX|  S)z
    Given a URL (absolute or relative), try to get its translated version in
    the `lang_code` language (either by i18n_patterns or by translated regex).
    Return the original URL if no translated version is found.
    z%s:%sr#   r$   N)r   rm   rk   r5   r*   r%   r   r   r#   r$   r6   r   schemenetlocqueryfragment)r   Z	lang_codeparsedrl   Zto_be_reversedr   r   r   translate_url  s    ("-r   )Er]   
__future__r   r}   rV   r   	importlibr   	threadingr   Zdjango.core.exceptionsr   r   Zdjango.httpr   Zdjango.utilsr   r	   Zdjango.utils.datastructuresr
   Zdjango.utils.deprecationr   Zdjango.utils.encodingr   r   r   Zdjango.utils.functionalr   r   Zdjango.utils.httpr   r   Zdjango.utils.module_loadingr   Zdjango.utils.regex_helperr   Z#django.utils.six.moves.urllib.parser   r   Zdjango.utils.translationr   r   r   r   objectr   r5   	Exceptionr6   rB   rG   rK   r;   rR   r_   rE   r   rm   r   rZ   Zreverse_lazyr   r   r   r   r   r   r   r   r   r   r   r   <module>   sX   		$@	
#2A		
