PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/cloudlinux/venv/lib/python3.11/site-packages/mako
Viewing File: /opt/cloudlinux/venv/lib/python3.11/site-packages/mako/runtime.py
# mako/runtime.py # Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php """provides runtime services for templates, including Context, Namespace, and various helper functions.""" import builtins import functools import sys from mako import compat from mako import exceptions from mako import util class Context: """Provides runtime namespace, output buffer, and various callstacks for templates. See :ref:`runtime_toplevel` for detail on the usage of :class:`.Context`. """ def __init__(self, buffer, **data): self._buffer_stack = [buffer] self._data = data self._kwargs = data.copy() self._with_template = None self._outputting_as_unicode = None self.namespaces = {} # "capture" function which proxies to the # generic "capture" function self._data["capture"] = functools.partial(capture, self) # "caller" stack used by def calls with content self.caller_stack = self._data["caller"] = CallerStack() def _set_with_template(self, t): self._with_template = t illegal_names = t.reserved_names.intersection(self._data) if illegal_names: raise exceptions.NameConflictError( "Reserved words passed to render(): %s" % ", ".join(illegal_names) ) @property def lookup(self): """Return the :class:`.TemplateLookup` associated with this :class:`.Context`. """ return self._with_template.lookup @property def kwargs(self): """Return the dictionary of top level keyword arguments associated with this :class:`.Context`. This dictionary only includes the top-level arguments passed to :meth:`.Template.render`. It does not include names produced within the template execution such as local variable names or special names such as ``self``, ``next``, etc. The purpose of this dictionary is primarily for the case that a :class:`.Template` accepts arguments via its ``<%page>`` tag, which are normally expected to be passed via :meth:`.Template.render`, except the template is being called in an inheritance context, using the ``body()`` method. :attr:`.Context.kwargs` can then be used to propagate these arguments to the inheriting template:: ${next.body(**context.kwargs)} """ return self._kwargs.copy() def push_caller(self, caller): """Push a ``caller`` callable onto the callstack for this :class:`.Context`.""" self.caller_stack.append(caller) def pop_caller(self): """Pop a ``caller`` callable onto the callstack for this :class:`.Context`.""" del self.caller_stack[-1] def keys(self): """Return a list of all names established in this :class:`.Context`.""" return list(self._data.keys()) def __getitem__(self, key): if key in self._data: return self._data[key] else: return builtins.__dict__[key] def _push_writer(self): """push a capturing buffer onto this Context and return the new writer function.""" buf = util.FastEncodingBuffer() self._buffer_stack.append(buf) return buf.write def _pop_buffer_and_writer(self): """pop the most recent capturing buffer from this Context and return the current writer after the pop. """ buf = self._buffer_stack.pop() return buf, self._buffer_stack[-1].write def _push_buffer(self): """push a capturing buffer onto this Context.""" self._push_writer() def _pop_buffer(self): """pop the most recent capturing buffer from this Context.""" return self._buffer_stack.pop() def get(self, key, default=None): """Return a value from this :class:`.Context`.""" return self._data.get(key, builtins.__dict__.get(key, default)) def write(self, string): """Write a string to this :class:`.Context` object's underlying output buffer.""" self._buffer_stack[-1].write(string) def writer(self): """Return the current writer function.""" return self._buffer_stack[-1].write def _copy(self): c = Context.__new__(Context) c._buffer_stack = self._buffer_stack c._data = self._data.copy() c._kwargs = self._kwargs c._with_template = self._with_template c._outputting_as_unicode = self._outputting_as_unicode c.namespaces = self.namespaces c.caller_stack = self.caller_stack return c def _locals(self, d): """Create a new :class:`.Context` with a copy of this :class:`.Context`'s current state, updated with the given dictionary. The :attr:`.Context.kwargs` collection remains unaffected. """ if not d: return self c = self._copy() c._data.update(d) return c def _clean_inheritance_tokens(self): """create a new copy of this :class:`.Context`. with tokens related to inheritance state removed.""" c = self._copy() x = c._data x.pop("self", None) x.pop("parent", None) x.pop("next", None) return c class CallerStack(list): def __init__(self): self.nextcaller = None def __nonzero__(self): return self.__bool__() def __bool__(self): return len(self) and self._get_caller() and True or False def _get_caller(self): # this method can be removed once # codegen MAGIC_NUMBER moves past 7 return self[-1] def __getattr__(self, key): return getattr(self._get_caller(), key) def _push_frame(self): frame = self.nextcaller or None self.append(frame) self.nextcaller = None return frame def _pop_frame(self): self.nextcaller = self.pop() class Undefined: """Represents an undefined value in a template. All template modules have a constant value ``UNDEFINED`` present which is an instance of this object. """ def __str__(self): raise NameError("Undefined") def __nonzero__(self): return self.__bool__() def __bool__(self): return False UNDEFINED = Undefined() STOP_RENDERING = "" class LoopStack: """a stack for LoopContexts that implements the context manager protocol to automatically pop off the top of the stack on context exit """ def __init__(self): self.stack = [] def _enter(self, iterable): self._push(iterable) return self._top def _exit(self): self._pop() return self._top @property def _top(self): if self.stack: return self.stack[-1] else: return self def _pop(self): return self.stack.pop() def _push(self, iterable): new = LoopContext(iterable) if self.stack: new.parent = self.stack[-1] return self.stack.append(new) def __getattr__(self, key): raise exceptions.RuntimeException("No loop context is established") def __iter__(self): return iter(self._top) class LoopContext: """A magic loop variable. Automatically accessible in any ``% for`` block. See the section :ref:`loop_context` for usage notes. :attr:`parent` -> :class:`.LoopContext` or ``None`` The parent loop, if one exists. :attr:`index` -> `int` The 0-based iteration count. :attr:`reverse_index` -> `int` The number of iterations remaining. :attr:`first` -> `bool` ``True`` on the first iteration, ``False`` otherwise. :attr:`last` -> `bool` ``True`` on the last iteration, ``False`` otherwise. :attr:`even` -> `bool` ``True`` when ``index`` is even. :attr:`odd` -> `bool` ``True`` when ``index`` is odd. """ def __init__(self, iterable): self._iterable = iterable self.index = 0 self.parent = None def __iter__(self): for i in self._iterable: yield i self.index += 1 @util.memoized_instancemethod def __len__(self): return len(self._iterable) @property def reverse_index(self): return len(self) - self.index - 1 @property def first(self): return self.index == 0 @property def last(self): return self.index == len(self) - 1 @property def even(self): return not self.odd @property def odd(self): return bool(self.index % 2) def cycle(self, *values): """Cycle through values as the loop progresses.""" if not values: raise ValueError("You must provide values to cycle through") return values[self.index % len(values)] class _NSAttr: def __init__(self, parent): self.__parent = parent def __getattr__(self, key): ns = self.__parent while ns: if hasattr(ns.module, key): return getattr(ns.module, key) else: ns = ns.inherits raise AttributeError(key) class Namespace: """Provides access to collections of rendering methods, which can be local, from other templates, or from imported modules. To access a particular rendering method referenced by a :class:`.Namespace`, use plain attribute access: .. sourcecode:: mako ${some_namespace.foo(x, y, z)} :class:`.Namespace` also contains several built-in attributes described here. """ def __init__( self, name, context, callables=None, inherits=None, populate_self=True, calling_uri=None, ): self.name = name self.context = context self.inherits = inherits if callables is not None: self.callables = {c.__name__: c for c in callables} callables = () module = None """The Python module referenced by this :class:`.Namespace`. If the namespace references a :class:`.Template`, then this module is the equivalent of ``template.module``, i.e. the generated module for the template. """ template = None """The :class:`.Template` object referenced by this :class:`.Namespace`, if any. """ context = None """The :class:`.Context` object for this :class:`.Namespace`. Namespaces are often created with copies of contexts that contain slightly different data, particularly in inheritance scenarios. Using the :class:`.Context` off of a :class:`.Namespace` one can traverse an entire chain of templates that inherit from one-another. """ filename = None """The path of the filesystem file used for this :class:`.Namespace`'s module or template. If this is a pure module-based :class:`.Namespace`, this evaluates to ``module.__file__``. If a template-based namespace, it evaluates to the original template file location. """ uri = None """The URI for this :class:`.Namespace`'s template. I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`. This is the equivalent of :attr:`.Template.uri`. """ _templateuri = None @util.memoized_property def attr(self): """Access module level attributes by name. This accessor allows templates to supply "scalar" attributes which are particularly handy in inheritance relationships. .. seealso:: :ref:`inheritance_attr` :ref:`namespace_attr_for_includes` """ return _NSAttr(self) def get_namespace(self, uri): """Return a :class:`.Namespace` corresponding to the given ``uri``. If the given ``uri`` is a relative URI (i.e. it does not contain a leading slash ``/``), the ``uri`` is adjusted to be relative to the ``uri`` of the namespace itself. This method is therefore mostly useful off of the built-in ``local`` namespace, described in :ref:`namespace_local`. In most cases, a template wouldn't need this function, and should instead use the ``<%namespace>`` tag to load namespaces. However, since all ``<%namespace>`` tags are evaluated before the body of a template ever runs, this method can be used to locate namespaces using expressions that were generated within the body code of the template, or to conditionally use a particular namespace. """ key = (self, uri) if key in self.context.namespaces: return self.context.namespaces[key] ns = TemplateNamespace( uri, self.context._copy(), templateuri=uri, calling_uri=self._templateuri, ) self.context.namespaces[key] = ns return ns def get_template(self, uri): """Return a :class:`.Template` from the given ``uri``. The ``uri`` resolution is relative to the ``uri`` of this :class:`.Namespace` object's :class:`.Template`. """ return _lookup_template(self.context, uri, self._templateuri) def get_cached(self, key, **kwargs): """Return a value from the :class:`.Cache` referenced by this :class:`.Namespace` object's :class:`.Template`. The advantage to this method versus direct access to the :class:`.Cache` is that the configuration parameters declared in ``<%page>`` take effect here, thereby calling up the same configured backend as that configured by ``<%page>``. """ return self.cache.get(key, **kwargs) @property def cache(self): """Return the :class:`.Cache` object referenced by this :class:`.Namespace` object's :class:`.Template`. """ return self.template.cache def include_file(self, uri, **kwargs): """Include a file at the given ``uri``.""" _include_file(self.context, uri, self._templateuri, **kwargs) def _populate(self, d, l): for ident in l: if ident == "*": for (k, v) in self._get_star(): d[k] = v else: d[ident] = getattr(self, ident) def _get_star(self): if self.callables: for key in self.callables: yield (key, self.callables[key]) def __getattr__(self, key): if key in self.callables: val = self.callables[key] elif self.inherits: val = getattr(self.inherits, key) else: raise AttributeError( "Namespace '%s' has no member '%s'" % (self.name, key) ) setattr(self, key, val) return val class TemplateNamespace(Namespace): """A :class:`.Namespace` specific to a :class:`.Template` instance.""" def __init__( self, name, context, template=None, templateuri=None, callables=None, inherits=None, populate_self=True, calling_uri=None, ): self.name = name self.context = context self.inherits = inherits if callables is not None: self.callables = {c.__name__: c for c in callables} if templateuri is not None: self.template = _lookup_template(context, templateuri, calling_uri) self._templateuri = self.template.module._template_uri elif template is not None: self.template = template self._templateuri = template.module._template_uri else: raise TypeError("'template' argument is required.") if populate_self: lclcallable, lclcontext = _populate_self_namespace( context, self.template, self_ns=self ) @property def module(self): """The Python module referenced by this :class:`.Namespace`. If the namespace references a :class:`.Template`, then this module is the equivalent of ``template.module``, i.e. the generated module for the template. """ return self.template.module @property def filename(self): """The path of the filesystem file used for this :class:`.Namespace`'s module or template. """ return self.template.filename @property def uri(self): """The URI for this :class:`.Namespace`'s template. I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`. This is the equivalent of :attr:`.Template.uri`. """ return self.template.uri def _get_star(self): if self.callables: for key in self.callables: yield (key, self.callables[key]) def get(key): callable_ = self.template._get_def_callable(key) return functools.partial(callable_, self.context) for k in self.template.module._exports: yield (k, get(k)) def __getattr__(self, key): if key in self.callables: val = self.callables[key] elif self.template.has_def(key): callable_ = self.template._get_def_callable(key) val = functools.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) else: raise AttributeError( "Namespace '%s' has no member '%s'" % (self.name, key) ) setattr(self, key, val) return val class ModuleNamespace(Namespace): """A :class:`.Namespace` specific to a Python module instance.""" def __init__( self, name, context, module, callables=None, inherits=None, populate_self=True, calling_uri=None, ): self.name = name self.context = context self.inherits = inherits if callables is not None: self.callables = {c.__name__: c for c in callables} mod = __import__(module) for token in module.split(".")[1:]: mod = getattr(mod, token) self.module = mod @property def filename(self): """The path of the filesystem file used for this :class:`.Namespace`'s module or template. """ return self.module.__file__ def _get_star(self): if self.callables: for key in self.callables: yield (key, self.callables[key]) for key in dir(self.module): if key[0] != "_": callable_ = getattr(self.module, key) if callable(callable_): yield key, functools.partial(callable_, self.context) def __getattr__(self, key): if key in self.callables: val = self.callables[key] elif hasattr(self.module, key): callable_ = getattr(self.module, key) val = functools.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) else: raise AttributeError( "Namespace '%s' has no member '%s'" % (self.name, key) ) setattr(self, key, val) return val def supports_caller(func): """Apply a caller_stack compatibility decorator to a plain Python function. See the example in :ref:`namespaces_python_modules`. """ def wrap_stackframe(context, *args, **kwargs): context.caller_stack._push_frame() try: return func(context, *args, **kwargs) finally: context.caller_stack._pop_frame() return wrap_stackframe def capture(context, callable_, *args, **kwargs): """Execute the given template def, capturing the output into a buffer. See the example in :ref:`namespaces_python_modules`. """ if not callable(callable_): raise exceptions.RuntimeException( "capture() function expects a callable as " "its argument (i.e. capture(func, *args, **kwargs))" ) context._push_buffer() try: callable_(*args, **kwargs) finally: buf = context._pop_buffer() return buf.getvalue() def _decorate_toplevel(fn): def decorate_render(render_fn): def go(context, *args, **kw): def y(*args, **kw): return render_fn(context, *args, **kw) try: y.__name__ = render_fn.__name__[7:] except TypeError: # < Python 2.4 pass return fn(y)(context, *args, **kw) return go return decorate_render def _decorate_inline(context, fn): def decorate_render(render_fn): dec = fn(render_fn) def go(*args, **kw): return dec(context, *args, **kw) return go return decorate_render def _include_file(context, uri, calling_uri, **kwargs): """locate the template from the given uri and include it in the current output.""" template = _lookup_template(context, uri, calling_uri) (callable_, ctx) = _populate_self_namespace( context._clean_inheritance_tokens(), template ) kwargs = _kwargs_for_include(callable_, context._data, **kwargs) if template.include_error_handler: try: callable_(ctx, **kwargs) except Exception: result = template.include_error_handler(ctx, compat.exception_as()) if not result: raise else: callable_(ctx, **kwargs) def _inherit_from(context, uri, calling_uri): """called by the _inherit method in template modules to set up the inheritance chain at the start of a template's execution.""" if uri is None: return None template = _lookup_template(context, uri, calling_uri) self_ns = context["self"] ih = self_ns while ih.inherits is not None: ih = ih.inherits lclcontext = context._locals({"next": ih}) ih.inherits = TemplateNamespace( "self:%s" % template.uri, lclcontext, template=template, populate_self=False, ) context._data["parent"] = lclcontext._data["local"] = ih.inherits callable_ = getattr(template.module, "_mako_inherit", None) if callable_ is not None: ret = callable_(template, lclcontext) if ret: return ret gen_ns = getattr(template.module, "_mako_generate_namespaces", None) if gen_ns is not None: gen_ns(context) return (template.callable_, lclcontext) def _lookup_template(context, uri, relativeto): lookup = context._with_template.lookup if lookup is None: raise exceptions.TemplateLookupException( "Template '%s' has no TemplateLookup associated" % context._with_template.uri ) uri = lookup.adjust_uri(uri, relativeto) try: return lookup.get_template(uri) except exceptions.TopLevelLookupException as e: raise exceptions.TemplateLookupException( str(compat.exception_as()) ) from e def _populate_self_namespace(context, template, self_ns=None): if self_ns is None: self_ns = TemplateNamespace( "self:%s" % template.uri, context, template=template, populate_self=False, ) context._data["self"] = context._data["local"] = self_ns if hasattr(template.module, "_mako_inherit"): ret = template.module._mako_inherit(template, context) if ret: return ret return (template.callable_, context) def _render(template, callable_, args, data, as_unicode=False): """create a Context and return the string output of the given template and template callable.""" if as_unicode: buf = util.FastEncodingBuffer() else: buf = util.FastEncodingBuffer( encoding=template.output_encoding, errors=template.encoding_errors ) context = Context(buf, **data) context._outputting_as_unicode = as_unicode context._set_with_template(template) _render_context( template, callable_, context, *args, **_kwargs_for_callable(callable_, data), ) return context._pop_buffer().getvalue() def _kwargs_for_callable(callable_, data): argspec = compat.inspect_getargspec(callable_) # for normal pages, **pageargs is usually present if argspec[2]: return data # for rendering defs from the top level, figure out the args namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None] kwargs = {} for arg in namedargs: if arg != "context" and arg in data and arg not in kwargs: kwargs[arg] = data[arg] return kwargs def _kwargs_for_include(callable_, data, **kwargs): argspec = compat.inspect_getargspec(callable_) namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None] for arg in namedargs: if arg != "context" and arg in data and arg not in kwargs: kwargs[arg] = data[arg] return kwargs def _render_context(tmpl, callable_, context, *args, **kwargs): import mako.template as template # create polymorphic 'self' namespace for this # template with possibly updated context if not isinstance(tmpl, template.DefTemplate): # if main render method, call from the base of the inheritance stack (inherit, lclcontext) = _populate_self_namespace(context, tmpl) _exec_template(inherit, lclcontext, args=args, kwargs=kwargs) else: # otherwise, call the actual rendering method specified (inherit, lclcontext) = _populate_self_namespace(context, tmpl.parent) _exec_template(callable_, context, args=args, kwargs=kwargs) def _exec_template(callable_, context, args=None, kwargs=None): """execute a rendering callable given the callable, a Context, and optional explicit arguments the contextual Template will be located if it exists, and the error handling options specified on that Template will be interpreted here. """ template = context._with_template if template is not None and ( template.format_exceptions or template.error_handler ): try: callable_(context, *args, **kwargs) except Exception: _render_error(template, context, compat.exception_as()) except: e = sys.exc_info()[0] _render_error(template, context, e) else: callable_(context, *args, **kwargs) def _render_error(template, context, error): if template.error_handler: result = template.error_handler(context, error) if not result: tp, value, tb = sys.exc_info() if value and tb: raise value.with_traceback(tb) else: raise error else: error_template = exceptions.html_error_template() if context._outputting_as_unicode: context._buffer_stack[:] = [util.FastEncodingBuffer()] else: context._buffer_stack[:] = [ util.FastEncodingBuffer( error_template.output_encoding, error_template.encoding_errors, ) ] context._set_with_template(error_template) error_template.render_context(context, error=error)