4V=jddlmZddlZddlZddlZddlmZddlm Z ddl m Z ddl m Z ddlmZdd lmZd d lmZejr d d lmZd d lmZGddejZeGddZejdejZejdZejdejZddddZ dd#Z#Gd$d%Z$Gd&d'e$Z%Gd(d)e$Z&Gd*d+e$Z'Gd,d-Z(Gd.d/e$Z)ej*d0ej+1Z,d?d5Z-d6Z.d7Z/e-e/ej0Z1e-d8ej2e-d9ej2fZ3Gd:d;e$Z4dS)@) annotationsN) dataclass)Template)CodeType)quote)iter_multi_items) _urlencode)ValidationError) BaseConverter)Mapc8eZdZUded<ded<ded<ded<dS) Weightingintnumber_static_weightszlist[tuple[int, int]]static_weightsnumber_argument_weightsz list[int]argument_weightsN)__name__ __module__ __qualname____annotations__DC:\PYTHON\_runtimes\venv\Lib\site-packages\werkzeug/routing/rules.pyrrsB))))    rrcFeZdZUdZded<ded<ded<ded<ded <d S) RuleParta$A part of a rule. Rules can be represented by parts as delimited by `/` with instances of this class representing those parts. The *content* is either the raw content if *static* or a regex string to match against. The *weight* can be used to order parts when matching. strcontentboolfinalstaticsuffixedrweightN)rrr__doc__rrrrrrsNLLLKKKLLLNNNrra (?: (?P/) # a slash | (?P[^[a-zA-Z_][a-zA-Z0-9_]*) # converter name (?:\((?P.*?)\))? # converter arguments : # variable delimiter )? (?P[a-zA-Z_][a-zA-Z0-9_]*) # variable name > ) ) z <([^>]+)>z \s* ((?P\w+)\s*=\s*)? (?P True|False| \d+.\d+| \d+.| \d+| [\w\d_.]+| [urUR]?(?P"[^"]*?"|'[^']*') )\s*, TF)NoneTrueFalsevaluertargetposrreturncn |||S#t$rt|cYSwxYw)zgFind the *target* in *value* after *pos*. Returns the *value* length if *target* isn't found. )index ValueErrorlen)r*r+r,s r_findr2WsH {{63''' 5zzs 44None | bool | int | float | strc|tvr t|SttfD]} ||cS#t$rYwxYw|dd|ddkr|ddvr |dd}t |S)Nr rz"')_PYTHON_CONSTANTSrfloatr0r)r*converts r _pythonizer9bs !!! '': 75>> ! ! !    D  RaRyE"##J58u#4#4ad  u::s 5 AAargstr*tuple[tuple[t.Any, ...], dict[str, t.Any]]c&|dz }g}i}d}t|D]}||kr-td|||d|d}||d}t |}|ds||n|d}|||<|}t||fS)N,rz!Cannot parse converter argument '' stringvalr*name) _converter_args_refinditerstartr0groupr9appendendtuple)r:argskwargspositionitemr*r@s rparse_converter_argsrLos cMF D FH"++F33 ::<<8 # #VF8djjll;R4SVVV  ;'' =JJw''E5!!zz&!! ! KK    ::f%%D F4L88:: ;; rceZdZdZddZdS) RuleFactoryzAs soon as you have more complex URL setups it's a good idea to use rule factories to avoid repetitive tasks. Some of them are builtin, others can be added by subclassing `RuleFactory` and overriding `get_rules`. maprr-t.Iterable[Rule]ct)zaSubclasses of `RuleFactory` have to override this method and return an iterable of rules.)NotImplementedErrorselfrOs r get_ruleszRuleFactory.get_ruless"###rN)rOrr-rP)rrrr&rUrrrrNrNs2 $$$$$$rrNc"eZdZdZddZdd Zd S) SubdomainaAll URLs provided by this factory have the subdomain set to a specific domain. For example if you want to use the subdomain for the current language this can be a good setup:: url_map = Map([ Rule('/', endpoint='#select_language'), Subdomain('', [ Rule('/', endpoint='index'), Rule('/about', endpoint='about'), Rule('/help', endpoint='help') ]) ]) All the rules except for the ``'#select_language'`` endpoint will now listen on a two letter long subdomain that holds the language code for the current request. subdomainrrulest.Iterable[RuleFactory]r-r'c"||_||_dSN)rXrY)rTrXrYs r__init__zSubdomain.__init__s" rrOrt.Iterator[Rule]c#K|jD]>}||D]&}|}|j|_|V'?dSr\)rYrUemptyrXrTrO rulefactoryrules rrUzSubdomain.get_rulessd:  K#--c22  zz||!%    rN)rXrrYrZr-r'rOrr-r^rrrr&r]rUrrrrWrWsF$rrWc"eZdZdZddZdd Zd S)Submounta}Like `Subdomain` but prefixes the URL rule with a given string:: url_map = Map([ Rule('/', endpoint='index'), Submount('/blog', [ Rule('/', endpoint='blog/index'), Rule('/entry/', endpoint='blog/show') ]) ]) Now the rule ``'blog/show'`` matches ``/blog/entry/``. pathrrYrZr-r'cH|d|_||_dS)N/)rstriprhrY)rTrhrYs rr]zSubmount.__init__s KK$$  rrOrr^c#K|jD]F}||D].}|}|j|jz|_|V/GdSr\)rYrUr`rhrcras rrUzSubmount.get_rulessk:  K#--c22  zz|| I 1     rN)rhrrYrZr-r'rdrerrrrgrgsF  rrgc"eZdZdZddZdd Zd S)EndpointPrefixaPrefixes all endpoints (which must be strings for this factory) with another string. This can be useful for sub applications:: url_map = Map([ Rule('/', endpoint='index'), EndpointPrefix('blog/', [Submount('/blog', [ Rule('/', endpoint='index'), Rule('/entry/', endpoint='show') ])]) ]) prefixrrYrZr-r'c"||_||_dSr\)rorY)rTrorYs rr]zEndpointPrefix.__init__s  rrOrr^c#K|jD]F}||D].}|}|j|jz|_|V/GdSr\)rYrUr`roendpointras rrUzEndpointPrefix.get_rulessk:  K#--c22  zz|| $ dm ;     rN)rorrYrZr-r'rdrerrrrnrnsF  rrnc"eZdZdZd dZdd Zd S) RuleTemplateaXReturns copies of the rules wrapped and expands string templates in the endpoint, rule, defaults or subdomain sections. Here a small example for such a rule template:: from werkzeug.routing import Map, Rule, RuleTemplate resource = RuleTemplate([ Rule('/$name/', endpoint='$name.list'), Rule('/$name/', endpoint='$name.show') ]) url_map = Map([resource(name='user'), resource(name='page')]) When a rule template is called the keyword arguments are used to replace the placeholders in all the string parameters. rYrPr-r'c.t||_dSr\)listrY)rTrYs rr]zRuleTemplate.__init__s%[[ rrHt.AnyrIRuleTemplateFactoryc@t|jt|i|Sr\)rxrYdict)rTrHrIs r__call__zRuleTemplate.__call__s!"4:tT/DV/D/DEEErN)rYrPr-r')rHrwrIrwr-rx)rrrr&r]r{rrrrtrtsL$!!!!FFFFFFrrtc"eZdZdZddZdd Zd S)rxzsA factory that fills in template variables into rules. Used by `RuleTemplate` internally. :internal: rYrZcontextdict[str, t.Any]r-r'c"||_||_dSr\)rYr})rTrYr}s rr]zRuleTemplateFactory.__init__s  rrOrr^c #K|jD]P}||D]6}dx}}|jrbi}|jD]F\}}t |t r't ||j}|||<G|j ,t |j |j}|j }t |t r't ||j}tt |j |j|||j |j||jV8RdSr\)rYrUdefaultsitems isinstancerr substituter}rXrrRulercmethods build_onlystrict_slashes) rTrOrbrc new_defaultsrXkeyr* new_endpoints rrUzRuleTemplateFactory.get_rulessm:  K#--c22  +// y=2#%L&*m&9&9&;&;22 U%eS11M$,UOO$>$>t|$L$LE,1 S))>- ( 8 8 C CDL Q QI#} lC00S#+L#9#9#D#DT\#R#RLTY''224<@@ LO '   rN)rYrZr}r~r-r'rdrerrrrxrxsF  rrx_ASTT)boundsrc expected_type type[_ASTT]c~tj|jd}t|tjr|j}t||s,t dt|jd|jtj |D]+}t|tj rd|j |_ ,|S)zEast parse and prefix names with `.` to avoid collision with user varsrzAST node is of type z, not .) astparsebodyrExprr* TypeErrortyperwalkNameid)rrtreenodes r _prefix_namesr+sIcNN'*D$!!z dM * *  V4::#6 V Vm>T V V   $$ dCH % % $#$'mmDG Krz#self._converters[{elem!r}].to_url()zpif kwargs: params = self._encode_query_vars(kwargs) q = "?" if params else "" else: q = params = "" qparamsceZdZdZ dGdHdZdIdZdJdZdKd!ZdLd"ZdMdNd$Z dOd+Z dPd-Z dQd0Z dLd1Z edRd6Z dSdTd9Z dSdUd<ZdVd=Z dWdXd?ZdYdAZdZdDZdZd[dEZd[dFZdS)\raA Rule represents one URL pattern. There are some options for `Rule` that change the way it behaves and are passed to the `Rule` constructor. Note that besides the rule-string all arguments *must* be keyword arguments in order to not break the application on Werkzeug upgrades. `string` Rule strings basically are just normal URL paths with placeholders in the format ```` where the converter and the arguments are optional. If no converter is defined the `default` converter is used which means `string` in the normal configuration. URL rules that end with a slash are branch URLs, others are leaves. If you have `strict_slashes` enabled (which is the default), all branch URLs that are matched without a trailing slash will trigger a redirect to the same URL with the missing slash appended. The converters are defined on the `Map`. `endpoint` The endpoint for this rule. This can be anything. A reference to a function, a string, a number etc. The preferred way is using a string because the endpoint is used for URL generation. `defaults` An optional dict with defaults for other rules with the same endpoint. This is a bit tricky but useful if you want to have unique URLs:: url_map = Map([ Rule('/all/', defaults={'page': 1}, endpoint='all_entries'), Rule('/all/page/', endpoint='all_entries') ]) If a user now visits ``http://example.com/all/page/1`` they will be redirected to ``http://example.com/all/``. If `redirect_defaults` is disabled on the `Map` instance this will only affect the URL generation. `subdomain` The subdomain rule string for this rule. If not specified the rule only matches for the `default_subdomain` of the map. If the map is not bound to a subdomain this feature is disabled. Can be useful if you want to have user profiles on different subdomains and all subdomains are forwarded to your application:: url_map = Map([ Rule('/', subdomain='', endpoint='user/homepage'), Rule('/stats', subdomain='', endpoint='user/stats') ]) `methods` A sequence of http methods this rule applies to. If not specified, all methods are allowed. For example this can be useful if you want different endpoints for `POST` and `GET`. If methods are defined and the path matches but the method matched against is not in this list or in the list of another rule for that path the error raised is of the type `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the list of methods and `HEAD` is not, `HEAD` is added automatically. `strict_slashes` Override the `Map` setting for `strict_slashes` only for this rule. If not specified the `Map` setting is used. `merge_slashes` Override :attr:`Map.merge_slashes` for this rule. `build_only` Set this to True and the rule will never match but will create a URL that can be build. This is useful if you have resources on a subdomain or folder that are not handled by the WSGI application (like static data) `redirect_to` If given this must be either a string or callable. In case of a callable it's called with the url adapter that triggered the match and the values of the URL as keyword arguments and has to return the target for the redirect, otherwise it has to be a string with placeholders in rule syntax:: def foo_with_slug(adapter, id): # ask the database for the slug for the old id. this of # course has nothing to do with werkzeug. return f'foo/{Foo.get_slug_for_id(id)}' url_map = Map([ Rule('/foo/', endpoint='foo'), Rule('/some/old/url/', redirect_to='foo/'), Rule('/other/old/url/', redirect_to=foo_with_slug) ]) When the rule is matched the routing system will raise a `RequestRedirect` exception with the target for the redirect. Keep in mind that the URL will be joined against the URL root of the script so don't use a leading slash on the target URL unless you really mean root of that domain. `alias` If enabled this rule serves as an alias for another rule with the same endpoint and arguments. `host` If provided and the URL map has host matching enabled this can be used to provide a match rule for the whole host. This also means that the subdomain feature is disabled. `websocket` If ``True``, this rule is only matches for WebSocket (``ws://``, ``wss://``) requests. By default, rules will only match for HTTP requests. .. versionchanged:: 2.1 Percent-encoded newlines (``%0a``), which are decoded by WSGI servers, are considered when routing instead of terminating the match early. .. versionadded:: 1.0 Added ``websocket``. .. versionadded:: 1.0 Added ``merge_slashes``. .. versionadded:: 0.7 Added ``alias`` and ``host``. .. versionchanged:: 0.6.1 ``HEAD`` is added to ``methods`` if ``GET`` is present. NFstringrrt.Mapping[str, t.Any] | NonerX str | Nonert.Iterable[str] | Nonerr!rr t.Any | Noner bool | None merge_slashes redirect_to!str | t.Callable[..., str] | Nonealiashost websocketr-r'c |dstd|d||_|d |_|d|_d|_||_||_||_ | |_ ||_ ||_ | |_ | |_|et|t rt#dd|D}d|vrd|vr|d| r|hdz rtd ||_||_| |_|r(t-t t ||_nt-|_i|_g|_g|_dS) Nrjz URL rule 'z' must start with a slash.z&'methods' should be a list of strings.c6h|]}|Sr)upper).0xs r z Rule.__init__..s 222Qqwwyy222rHEADGET>rrOPTIONSzBWebSocket rules can only use 'GET', 'HEAD', and 'OPTIONS' methods.) startswithr0rcendswithis_leaf is_branchrOrrrXrrrrrrrraddrrrrset arguments _converters_trace_parts) rTrrrXrrrrrrrrrrs rr]z Rule.__init__s  %% NL&LLLMM M !??3/// --,*"   $ "  '3'' J HIII22'222GW$$')9)9 F### W'A'A'AA  X ' &  # S(!3!344DNN UUDN57.0 &( rc\t||jfi|S)z Return an unbound copy of this rule. This can be useful if want to reuse an already bound URL for another map. See ``get_empty_kwargs`` to override what keyword arguments are provided to the new copy. )rrcget_empty_kwargsrTs rr`z Rule.emptys0tDzz$)??t'<'<'>'>???rt.Mapping[str, t.Any]c d}|jrt|j}t||j|j|j|j|j|j|j|j  S)a Provides kwargs for instantiating empty copy with empty() Use this method to provide custom keyword arguments to the subclass of ``Rule`` when calling ``some_rule.empty()``. Helpful when the subclass has custom keyword arguments that are needed at instantiation. Must return a ``dict`` that will be provided as kwargs to the new instance of ``Rule``, following the initial ``self.rule`` value which is always provided as the first, required positional argument. N) rrXrrrrrrrr) rrzrXrrrrrrrr)rTrs rrzRule.get_empty_kwargssf = +DM**HnL].(*    rrOrr^c#K|VdSr\rrSs rrUzRule.get_rules*s rc>||jddS)zqRebinds and refreshes the URL. Call this if you modified the rule in place. :internal: T)rebindN)bindrOrs rrefreshz Rule.refresh-s" $(4 (((((rrc|j|std|d|j||_|j |j|_|j |j|_|j |j|_|dS)zBind the url to a map and create a regular expression based on the information from the rule itself and the defaults from the map. :internal: Nz url rule z already bound to map )rO RuntimeErrorrrrXdefault_subdomaincompile)rTrOrs rrz Rule.bind5s 8  U4UUUUVV V   &"%"4D    %!$!2D  > ! 2DN r variable_nameconverter_namerHtuple[t.Any, ...]rIr c||jjvrtd|d|jj||jg|Ri|S)zWLooks up the converter for the given parameter. .. versionadded:: 0.9 zthe converter z does not exist)rO converters LookupError)rTrrrHrIs r get_converterzRule.get_converterFsZ !4 4 4P~PPPQQ Q2tx">248MdMMMfMMMr query_varsct|}|jjrt||jj}t |S)N)r)r rOsort_parameterssortedsort_keyr )rTrrs r_encode_query_varszRule._encode_query_varsUsA-=j-I-I 8 # 95dh&7888E%   rrct.Iterable[RulePart]c#Kd}d}g}g}d}d}d}|t|kr`t||} | td|| } | d|t|t| d f|jd| df||r| dntj| dz }| d|rtj|}d}t| dpd\} } | | d| d pd | | } | |j | d<|j | d| jsd}|d |d | jd z }|dz }|| j|jd| df| dy|jd|r|dz }nW|s|dz }t#t| |t| |}t%|||d|Vd}d}g}g}d}d}| }|t|k`d}|r|ddkrd}|dddz}|s|dz }t#t| |t| |}t%|||||V|rt%dddd|VdSdS)NTFrzmalformed url rule: r#variabler converterdefaultz(?P<__werkzeug_>)r slash)Frjrjz\Zr r"r#r$r%r5z (?':':Sh=P=P#:;;;VR4>>4>9R9RRJ+1 i00G#7[8I8OR#P#P ,,$d;&7&D9fh6= j!12""4 #3444-! EP-=PP PPPP A%  ''777 ""D$z*:#;<<<G}( ""<000)sNGG!)5(&^,,,&-...( F # '#%!&% !G!F')$%'N!E'($))++CqCIIoot  2WR[C''Hcrcl\1G  u G   ! " " "              %uV       rc |j Jd|jjr |jpd}n |jpd}g|_g|_i|_|dkr+tddddtdgdgg|_n-|j | ||j d|j }|j rtjd d |j }|j | |||d|d|_||d|d|_dS) z.Compiles the regular expression and stores it.Nzrule not boundrFTrr)F|z/{2,}rj)rO host_matchingrrXrrrrrextendrrErcrrsub_compile_builder__get___build_build_unknown)rT domain_rulercs rrz Rule.compiles~x##%5### 8 ! /)/rKK..BK   "  "$QAr22 DKK K  t// << = = = <(((y   36'3 22D 4++D11222 5++E22::4FF  ="33D99AA$MMrcoderr@ t.Callable[..., tuple[str, str]]c<i}i}t|||||Sr\)exec)rr@globslocss r_get_func_codezRule._get_func_codes("$!# T5$DzrTappend_unknownc $|jpig}g}|}|jD]\}}|dkr||ur|}|rB|vr>|j||}|d|fV|s'|dt |df|d|fd"d d#fd }||}||} |sg} n"t g} | td$d} | tj tj | || | gtj fd||zD} dD} tdtj}d|jd|_|jjtjdd| | zD]4}|jjtj|d5tjdd|j_| D]3}|jjtjd4| |_tjd}|g|_tj|D]L}d|jvrd|_d|jvr |j|_d|jvrd|_d|jvr |j|_Mt;|d d!}|||jS)%NrFz!$&'()*+,/:;=@)safeTelemrr-ast.Callctt|tj}tj|tjg|_|S)N)r)r_CALL_CONVERTER_CODE_FMTformatrCallrLoadrH)rrets r_convertz'Rule._compile_builder.._convertsF 8 ? ?T ? J JCHUUCsxzz223CHJropslist[tuple[bool, str]]list[ast.expr]crfd|D}|ptjdg}|dg}|ddD]|}t|tjrKt|dtjr+tj|dj|jz|d<g||}|S)NcXg|]&\}}|r |ntj|'Sr)rConstant)r is_dynamicrrs r z9Rule._compile_builder.._parts..sH%%%$J#-D#,t2D2D%%%rrrr r5)rrrr*rE)rpartsrprs rrz%Rule._compile_builder.._partss%%%%(+%%%E/cl2../E8*C122Y " "a..":c"gs|3T3T"!l3r7=17+BCCCGGJJqMMMMJrrast.exprc`t|dkr|dStj|S)Nr r)r1r JoinedStr)rs r_joinz$Rule._compile_builder.._joins*5zzQQx='' 'rc&g|] \}}|r|v |Srr)rrrrs rrz)Rule._compile_builder..!s<    D #(22 222rc,g|]}t|Sr)r)rks rrz)Rule._compile_builder..&s***AQ***rz def _(): passz r)rrr-r)rrr-r)rrr-r)rrrto_urlrEr_IF_KWARGS_URL_ENCODE_ASTr_URL_ENCODE_AST_NAMESrReturnTupler r FunctionDefrcr@rHargkwargrrrr _attributesr!r"r#r$rr)rTrdom_opsurl_opsoplrrr dom_parts url_partsrrpargskargsfunc_astr+_modulerrrrs @@rrzRule._compile_builders=&B*,*, $  ) ) Js{{sg~~ )dh..'-44Xd^DD E4=)))) ) E54D#E#E#EFGGGG D$<((((          F7OO F7OO  4DD-.D   2 3 3 3 ( ( ( ( Jsy%% "2"2EE)4D4D!EsxzzRR S S       $+g$5    +**** #/BB2DI222  !!#''4"8"89995= : :C M  % %cgc4&8&8 9 9 9 9!gi66  < rrr*s r suitable_forzRule.suitable_fords   (dl**5=&B>  C(""s&'8'8uu  !&nn.. ! ! U&==UfSk%9%9 55trtuple[int, int, int]cn|jrdndt|j t|jpd fS)z?The build compare key for sorting. :internal: r rr)rr1rrrs rbuild_compare_keyzRule.build_compare_keys< Z&QT^)<)<(WXXrotherobjectc\t|t|o|j|jkSr\)rrr)rTrDs r__eq__z Rule.__eq__s&%d,,L 1LLrc|jSr\)rcrs r__str__z Rule.__str__s yrc|jdt|jdSg}|jD]6\}}|r|d|d!||7d|d}|jdd|jdnd}dt|jd ||d |jdS) Nrrrz (z, r z -> ) rOrrrrEjoinlstriprrr)rTrrr parts_strrs r__repr__z Rule.__repr__s 8 7tDzz*777 7 $  # # J # [[[[)))) T""""GGENN))#.. 59\5M1tyy..1111SUS4::&SSSgSS4=SSSSr) NNNFNNNNFNF)rrrrrXrrrrr!rrrrrrrrrrr!rrrr!r-r')r-r)r-rrd)r-r')F)rOrrr!r-r') rrrrrHrrIrr-r )rrr-r)rcrr-r)rrr@rr-r)T)rr!r-r)r8rrr!r-r9)rcrr-r!r\)r8rr>rr-r!)r-rA)rDrEr-r!)r-r)rrrr&r]r`rrUrrrrrr staticmethodrrr;r=r@rCrG__hash__rIrPrrrrrIs'~~F26 $*. !%&*%)9=9)9)9)9)9)v@@@@    6))))" N N N N!!!![[[[z N N N ND\&*b8b8b8b8b8JEI     CGBYYYYMMMMH T T T T T Trr)r*rr+rr,rr-r)r*rr-r3)r:rr-r;)rrrrr-r)5 __future__rrrtypingt dataclassesrrrtypesr urllib.parserdatastructuresr urlsr rr TYPE_CHECKINGr rOr NamedTuplerrrVERBOSEr_simple_rule_rerAr6r2r9rLrNrWrgrnrtrxTypeVarASTrrr _IF_KWARGS_URL_ENCODE_CODEIfr&rr'rrrrrcs"""""" !!!!!!------''''''?))))))           " 2:$J'  ,"*\**RZ J "4%@@    4 $ $ $ $ $ $ $ $ >{4[2FFFFFFFF4$$$$$+$$$N  ')))    A*M*DcfMMM#sx  M(CH%% V TV TV TV TV T;V TV TV TV TV Tr