o xgm@sdZddlZddlZddlZddlZddlmZddlmZddl m Z ddl m Z ddl mZmZddlmZdd lmZmZdd lmZdd lmZdd lmZmZdd lmZmZddlm Z ddl!m"Z"ddl#m$Z$m%Z%ddl&m'Z'GdddZ(d.ddZ)ej*ddd.ddZ+ej*ddddZ,GdddZ-GdddZ.Gd d!d!e.Z/ed"Z0d/d$d%Z1Gd&d'd'e.Z2Gd(d)d)Z3Gd*d+d+Z4Gd,d-d-Z5dS)0z 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)Local)settings)ErrorWarning)check_resolver)ImproperlyConfiguredViewDoesNotExist)MultiValueDict)cached_property)RFC3986_SUBDELIMSescape_leading_slashes)_lazy_re_compile normalize) get_language) get_converter)NoReverseMatch Resolver404) get_callablec@s&eZdZdddZddZddZdS) ResolverMatchNc Cs||_||_||_||_||_||_|rdd|Dng|_d|j|_|r.dd|Dng|_ d|j |_ t |dsI|j j d|j j|_n |j d|j|_|pV|j} d|j | g|_dS)NcSg|]}|r|qSr.0xrr7/usr/lib/python3/dist-packages/django/urls/resolvers.py +z*ResolverMatch.__init__..:cSrrrrrrrr-r__name__.)funcargskwargsurl_nameroutetried app_namesjoinapp_name namespaces namespacehasattr __class__ __module__r! _func_path view_name) selfr#r$r%r&r)r,r'r( view_pathrrr__init__!s  zResolverMatch.__init__cCs|j|j|jf|SN)r#r$r%)r3indexrrr __getitem__:szResolverMatch.__getitem__cCs$d|j|j|j|j|j|j|jfS)Nz^ResolverMatch(func=%s, args=%s, kwargs=%s, url_name=%s, app_names=%s, namespaces=%s, route=%s))r1r$r%r&r)r,r'r3rrr__repr__=s zResolverMatch.__repr__)NNNNN)r!r0 __qualname__r5r8r:rrrrr s  rcCs|durtj}t|Sr6)r ROOT_URLCONF_get_cached_resolverurlconfrrr get_resolverDsr@)maxsizecCsttd|SN^/) URLResolver RegexPatternr>rrrr=Jsr=cCs.t|}t||_t||j}ttd|gSrB)rEdict convertersrD url_patterns) ns_patternresolverrGpattern ns_resolverrrrget_ns_resolverOs  rMc@seZdZddZdddZdS)LocaleRegexDescriptorcCs ||_dSr6)attr)r3rOrrrr5[ zLocaleRegexDescriptor.__init__NcCsj|dur|St||j}t|tr|||jd<|jdSt}||jvr0|t||j|<|j|S)zT Return a compiled regular expression based on the active language. Nregex)getattrrO isinstancestr_compile__dict__r _regex_dict)r3instanceclsrK language_coderrr__get__^s     zLocaleRegexDescriptor.__get__r6)r!r0r;r5r[rrrrrNZsrNc@seZdZddZddZdS) CheckURLMixincCs$d|}|jr|d|j7}|S)zI Format the URL pattern for display in warning messages. '{}'z [name='{}'])formatname)r3 descriptionrrrdescribers zCheckURLMixin.describecCsF|jj}tjs gS|dr!|ds!td|dd}|gSgS)zM Check that the pattern does not begin with a forward slash. )/rCz^\/rbzYour 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.W002id) rQrKr APPEND_SLASH startswithendswithrr^ra)r3 regex_patternwarningrrr_check_pattern_startswith_slash{sz-CheckURLMixin._check_pattern_startswith_slashN)r!r0r;rarjrrrrr\qs r\c@sFeZdZedZdddZddZdd Zd d Zd d Z ddZ dS)rE_regexNFcCs"||_i|_||_||_i|_dSr6)rkrW _is_endpointr_rG)r3rQr_ is_endpointrrrr5s  zRegexPattern.__init__cCst|jr|jjdr|j|n|j|}|r8|}|r dn|}dd|D}|| d||fSdS)N$rcSsi|] \}}|dur||qSr6rrkvrrr sz&RegexPattern.match..) rlrQrKrg fullmatchsearch groupdictgroupsitemsend)r3pathmatchr%r$rrrrzs  zRegexPattern.matchcCs*g}|||js|||Sr6)extendrjrl_check_include_trailing_dollarr3warningsrrrchecks zRegexPattern.checkcCs8|jj}|dr|dstd|ddgSgS)Nrnz\$zYour URL pattern {} uses include with a route ending with a '$'. Remove the dollar from the route to avoid problems including URLs.z urls.W001rc)rQrKrgrr^ra)r3rhrrrr|s z+RegexPattern._check_include_trailing_dollarc Cs:zt|WStjy}z td||f|d}~ww)z0Compile and return the given regular expression.z*"%s" is not a valid regular expression: %sN)recompileerrorr )r3rQerrrrUs  zRegexPattern._compilecC t|jSr6)rTrkr9rrr__str__rPzRegexPattern.__str__NF) r!r0r;rNrQr5rzrr|rUrrrrrrEs  rEz1<(?:(?P[^>:]+):)?(?P[^>]+)>Fc Cs*|}dg}i} t|}|s|t|not|tj s(t d||t|d| || d}|d}| sNt d||f|d}|durXd}zt|}Wntys} z t d ||f| d} ~ ww|||<|d |d |jd q|r|d d||fS)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/' returns '^foo\/(?P[0-9]+)' and {'pk': }. ^TuAURL route '%s' cannot contain whitespace in angle brackets <…>.N parameterzLURL route '%s' uses parameter name %r which isn't a valid Python identifier. converterrTz'URL route %r uses invalid converter %r.(?P<>)z\Z)_PATH_PARAMETER_COMPONENT_RErtappendrescapesetgroup isdisjointstring whitespacer startrx isidentifierrKeyErrorrQr*) r'rmoriginal_routepartsrGrzr raw_converterrrrrr_route_to_regexsX   rc@s>eZdZedZdddZddZdd Zd d Zd d Z dS) RoutePattern_routeNFcCs0||_i|_||_||_tt||d|_dS)Nr)rrWrlr_rrTrG)r3r'r_rmrrrr5s zRoutePattern.__init__c Csv|j|}|r9|}|D]\}}|j|}z ||||<Wqty-YdSw||dd|fSdSNr)rQrtrurwrG to_python ValueErrorrx)r3ryrzr%keyvaluerrrrrz s   zRoutePattern.matchcCsJ|}|j}d|vs|ds|dr#|td|dd|S)NrrrnzYour 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().z2_0.W001rc)rjrrfrgrrr^ra)r3r~r'rrrrs zRoutePattern.checkcCstt||jdS)Nr)rrrrl)r3r'rrrrU#zRoutePattern._compilecCrr6)rTrr9rrrr&rPzRoutePattern.__str__r) r!r0r;rNrQr5rzrrUrrrrrrs  rc@sNeZdZdddZeddZeddZdd Zd d Zd d Z ddZ dS)LocalePrefixPatternTcCs||_i|_dSr6)prefix_default_languagerG)r3rrrrr5+s zLocalePrefixPattern.__init__cCstt|jSr6)rrrlanguage_prefixr9rrrrQ/szLocalePrefixPattern.regexcCs(tptj}|tjkr|jsdSd|S)Nrz%s/)rr LANGUAGE_CODErr3rZrrrr4s z#LocalePrefixPattern.language_prefixcCs*|j}||r|t|ddifSdSr)rrflen)r3ryrrrrrz<s zLocalePrefixPattern.matchcCsgSr6rr9rrrrBszLocalePrefixPattern.checkcCs d|S)Nr])r^r9rrrraErPzLocalePrefixPattern.describecCs|jSr6)rr9rrrrHszLocalePrefixPattern.__str__N)T) r!r0r;r5propertyrQrrzrrarrrrrr*s    rc@sBeZdZdddZddZddZdd Zd d Zed d Z dS) URLPatternNcCs ||_||_|p i|_||_dSr6)rKcallback default_argsr_)r3rKrrr_rrrr5Ms  zURLPattern.__init__cCsd|jj|jfS)Nz<%s %s>)r/r!rKrar9rrrr:SrzURLPattern.__repr__cCs|}||j|Sr6)_check_pattern_namer{rKrr}rrrrVszURLPattern.checkcCs:|jjdurd|jjvrtd|jdd}|gSgS)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.W003rc)rKr_rr^ra)r3rirrrr[s zURLPattern._check_pattern_namecCsH|j|}|r"|\}}}||jt|j|||jjt|jdSdS)N)r')rKrzupdaterrrr_rT)r3ryrznew_pathr$r%rrrresolveis   zURLPattern.resolvecCsD|j}t|tjr |j}t|ds|jd|jjS|jd|j S)zw A string that identifies the view (e.g. 'path.to.view_function' or 'path.to.ClassBasedView'). r!r") rrS functoolspartialr#r.r0r/r!r;)r3rrrr lookup_strqs   zURLPattern.lookup_str)NN) r!r0r;r5r:rrrr rrrrrrLs rc@seZdZd$ddZddZddZdd Zd d Zed d Z eddZ eddZ e d%ddZ e ddZddZddZeddZeddZddZd d!Zd"d#ZdS)&rDNcCsT||_||_d|_|p i|_||_||_i|_i|_i|_t |_ d|_ t |_ dSr)rK urlconf_namerdefault_kwargsr-r+ _reverse_dict_namespace_dict _app_dictr_callback_strs _populatedr_local)r3rKrrr+r-rrrr5s  zURLResolver.__init__cCsPt|jtr|jrd|jdjj}nt|j}d|jj||j|j|j fS)Nz <%s list>rz<%s %s (%s:%s) %s>) rSrlistr/r!reprr+r-rKra)r3 urlconf_reprrrrr:s   zURLResolver.__repr__cCs:g}|jD] }|t|q|||p|jSr6)rHr{r_check_custom_error_handlersrKr)r3messagesrKrrrrs  zURLResolver.checkc Csg}dD]r\}}z||}Wn/ttfy>}z!t|jd|}dj||d}|t|t|ddWYd}~qd}~wwt |}dg|} z|j | Wqt yvdj||j d|j|d krgd nd d }|t|d dYqw|S)N))i)ir)ir)ir handler%szDThe custom handler{status_code} view '{path}' could not be imported.) status_coderyz urls.E008)hintrdzeThe custom handler{status_code} view '{path}' does not take the correct number of arguments ({args}).r"rzrequest, exceptionrequest)rryr$z urls.E007rc)resolve_error_handler ImportErrorr rRurlconf_moduler^rrrTinspect signaturebind TypeErrorr0r;) r3rrnum_parametershandlerrrymsgrr$rrrrs6      z(URLResolver._check_custom_error_handlersc Cst|jddr dSzd|j_t}i}i}t}t|jD]}|jjj}| dr/|dd}t |t rd|j |jt|jjj}||j|||j|jjf|jdurc||j|||j|jjfq||jr~||jg|j||f||j<nf|jD]0}|j|D]'\} } } } t|| } ||| || i| |ji|jj|jj| fqq|jD]\}\}}|jj}|jj||||f||<q|j D] \}}||g!|q|j |j q||j"|<||j#|<||j$|<d|_%Wd|j_dSd|j_w)N populatingFTrr)&rRrrr rreversedrHrKrQrfrSrraddrr appendlistrrrGr_ _populater+ setdefaultrr- reverse_dictgetlistrnamespace_dictrwrapp_dictr{rrrr)r3lookupsr,appsrZ url_pattern p_patternbitsr_matchespatdefaultsrG new_matchesr-prefix sub_patterncurrent_convertersr+namespace_listrrrrsj            zURLResolver._populatecC"t}||jvr ||j|Sr6)rrrrrrrr  zURLResolver.reverse_dictcCrr6)rrrrrrrrrzURLResolver.namespace_dictcCrr6)rrrrrrrrrzURLResolver.app_dictcs4|dur |gdS|fdd|DdS)Nc3s|]}g|VqdSr6r)rtrKrr sz,URLResolver._extend_tried..)rr{)r(rK sub_triedrrr _extend_triedszURLResolver._extend_triedcCs&|s|S|dr|dd}||S)z} z|||| jddWYd} ~ qd} ~ ww|ri||j } | |j |j} | sX||j} t |t r_dnt|j} ||||jt|j| | |j|jg|j|jg|j|| |j|S||gqt||dtd|i)Nrr(r)r(ryry)rTrKrzrHrrrr$getrrr%rSrr(rr#r&r+r)r-r,rr'r) r3ryr(rzrr$r%rK sub_matchrsub_match_dictsub_match_args current_routerrrr*sB   &       zURLResolver.resolvecCst|jtr t|jS|jSr6)rSrrTrr9rrrrPs  zURLResolver.urlconf_modulec CsPt|jd|j}zt|W|Sty'}z d}t|j|jd|d}~ww)N 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.)r_)rRriterrr r^r)r3patternsrrrrrrHWs zURLResolver.url_patternscCs8t|jd|d}|sddlm}t|d|}t|S)Nrr)urls)rRr django.confrr)r3 view_typerrrrrrfs  z!URLResolver.resolve_error_handlercOs|j|dg|Ri|S)Nr)_reverse_with_prefix)r3 lookup_viewr$r%rrrreverseoszURLResolver.reversec s|rrtd|js||j|}|D]\}}}} |D]\} } |r6t|t| kr.qtt| |} nt |  |rAqt fdd| DrOq} i} d}| D]&\}}|| vryz | | || |<WqYtyxd}Ynwt|| |<qY|sq|dd| }tdt||f|| rt|| td d }t|Sqqt|d d}t|d d}|dur|durd ||f}n|}dd|D}|r|rd|f}n rd}nd}d||t||f}t|dd|i}t|)Nz2Don't mix *args and **kwargs in call to reverse()!c3s$|] \}}|||kVqdSr6)rror%rrrs"z3URLResolver._reverse_with_prefix..TF%z%%z^%s%sz/~:@)safer0r!z%s.%scSsg|]\}}}}|qSrr)r_rKrrrrsz4URLResolver._reverse_with_prefix..zarguments '%s'zkeyword 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)rrrrrrrFziprsymmetric_difference differenceanyrwto_urlrTreplacerrtrrr rrRr)r3r_prefixr$r% possibilities possibilityrKrrGresultparamscandidate_substext_candidate_subsrzrprq candidate_paturlmn lookup_view_srarg_msgrrrrrrsr    &    z URLResolver._reverse_with_prefix)NNNr6)r!r0r;r5r:rrrrrrr staticmethodrrrrr rrHrrrrrrrrDs2  =     &   rDr6)F)6__doc__rrrr importlibr urllib.parser asgiref.localrrrdjango.core.checksrrdjango.core.checks.urlsrdjango.core.exceptionsr r django.utils.datastructuresr django.utils.functionalr django.utils.httpr rdjango.utils.regex_helperrrdjango.utils.translationrrGr exceptionsrrutilsrrr@ lru_cacher=rMrNr\rErrrrrrDrrrrsJ           $     !: .+"3